From c8ec30a0a4458c9ca53b603a78ac27b3f5ec69fa Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Sun, 8 Nov 2009 01:57:17 +0100 Subject: [PATCH 001/503] 2009-11-06 Felix Zielcke * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Set array->name to NULL. * disk/mdraid_linux.c (grub_raid_super_1x): New structure. (WriteMostly1): New macro. Set array->name to NULL for metadata format 0.90. Add support for metadata 1.x. Fix some comments. * disk/raid.c (): Add support for name based RAID arrays. Fix a few comments. * util/getroot.c (grub_util_get_grub_dev): Add support for /dev/md/name style devices. --- ChangeLog.raid | 11 +++ disk/dmraid_nvidia.c | 3 +- disk/mdraid_linux.c | 193 +++++++++++++++++++++++++++++++++++++++++-- disk/raid.c | 74 +++++++++-------- util/getroot.c | 14 ++++ 5 files changed, 252 insertions(+), 43 deletions(-) create mode 100644 ChangeLog.raid diff --git a/ChangeLog.raid b/ChangeLog.raid new file mode 100644 index 000000000..090e1edc7 --- /dev/null +++ b/ChangeLog.raid @@ -0,0 +1,11 @@ +2009-11-06 Felix Zielcke + + * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Set array->name to NULL. + * disk/mdraid_linux.c (grub_raid_super_1x): New structure. + (WriteMostly1): New macro. + Set array->name to NULL for metadata format 0.90. Add support for + metadata 1.x. Fix some comments. + * disk/raid.c (): Add support for name based RAID arrays. Fix a + few comments. + * util/getroot.c (grub_util_get_grub_dev): Add support for + /dev/md/name style devices. diff --git a/disk/dmraid_nvidia.c b/disk/dmraid_nvidia.c index 84dfad8c4..ed89854b3 100644 --- a/disk/dmraid_nvidia.c +++ b/disk/dmraid_nvidia.c @@ -1,7 +1,7 @@ /* dmraid_nvidia.c - module to handle Nvidia fakeraid. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * 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 @@ -132,6 +132,7 @@ grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) "Unsupported RAID level: %d", sb.array.raid_level); } + array->name = NULL; array->number = 0; array->total_devs = sb.array.total_volumes; array->chunk_size = sb.array.stripe_block_size; diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index 29a21b4c7..275267f72 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -1,7 +1,7 @@ -/* mdraid_linux.c - module to handle linux softraid. */ +/* mdraid_linux.c - module to handle Linux Software RAID. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * 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 @@ -159,32 +159,146 @@ struct grub_raid_super_09 struct grub_raid_disk_09 this_disk; } __attribute__ ((packed)); +/* + * The version-1 superblock : + * All numeric fields are little-endian. + * + * Total size: 256 bytes plus 2 per device. + * 1K allows 384 devices. + */ + +struct grub_raid_super_1x +{ + /* Constant array information - 128 bytes. */ + grub_uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian. */ + grub_uint32_t major_version; /* 1. */ + grub_uint32_t feature_map; /* Bit 0 set if 'bitmap_offset' is meaningful. */ + grub_uint32_t pad0; /* Always set to 0 when writing. */ + + grub_uint8_t set_uuid[16]; /* User-space generated. */ + char set_name[32]; /* Set and interpreted by user-space. */ + + grub_uint64_t ctime; /* Lo 40 bits are seconds, top 24 are microseconds or 0. */ + grub_uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5. */ + grub_uint32_t layout; /* only for raid5 and raid10 currently. */ + grub_uint64_t size; /* Used size of component devices, in 512byte sectors. */ + + grub_uint32_t chunksize; /* In 512byte sectors. */ + grub_uint32_t raid_disks; + grub_uint32_t bitmap_offset; /* Sectors after start of superblock that bitmap starts + * NOTE: signed, so bitmap can be before superblock + * only meaningful of feature_map[0] is set. + */ + + /* These are only valid with feature bit '4'. */ + grub_uint32_t new_level; /* New level we are reshaping to. */ + grub_uint64_t reshape_position; /* Next address in array-space for reshape. */ + grub_uint32_t delta_disks; /* Change in number of raid_disks. */ + grub_uint32_t new_layout; /* New layout. */ + grub_uint32_t new_chunk; /* New chunk size (512byte sectors). */ + grub_uint8_t pad1[128 - 124]; /* Set to 0 when written. */ + + /* Constant this-device information - 64 bytes. */ + grub_uint64_t data_offset; /* Sector start of data, often 0. */ + grub_uint64_t data_size; /* Sectors in this device that can be used for data. */ + grub_uint64_t super_offset; /* Sector start of this superblock. */ + grub_uint64_t recovery_offset; /* Sectors before this offset (from data_offset) have been recovered. */ + grub_uint32_t dev_number; /* Permanent identifier of this device - not role in raid. */ + grub_uint32_t cnt_corrected_read; /* Number of read errors that were corrected by re-writing. */ + grub_uint8_t device_uuid[16]; /* User-space setable, ignored by kernel. */ + grub_uint8_t devflags; /* Per-device flags. Only one defined... */ + grub_uint8_t pad2[64 - 57]; /* Set to 0 when writing. */ + + /* Array state information - 64 bytes. */ + grub_uint64_t utime; /* 40 bits second, 24 btes microseconds. */ + grub_uint64_t events; /* Incremented when superblock updated. */ + grub_uint64_t resync_offset; /* Data before this offset (from data_offset) known to be in sync. */ + grub_uint32_t sb_csum; /* Checksum upto devs[max_dev]. */ + grub_uint32_t max_dev; /* Size of devs[] array to consider. */ + grub_uint8_t pad3[64 - 32]; /* Set to 0 when writing. */ + + /* Device state information. Indexed by dev_number. + * 2 bytes per device. + * Note there are no per-device state flags. State information is rolled + * into the 'roles' value. If a device is spare or faulty, then it doesn't + * have a meaningful role. + */ + grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty. */ +} __attribute__ ((packed)); + +#define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ + 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; + grub_uint64_t size, sb_size; struct grub_raid_super_09 sb; + struct grub_raid_super_1x *sb_1x; grub_uint32_t *uuid; + grub_uint8_t minor_version; - /* The sector where the RAID superblock is stored, if available. */ + /* The sector where the mdraid 0.90 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, &sb)) return grub_errno; - /* Look whether there is a RAID superblock. */ - if (sb.md_magic != SB_MAGIC) + /* Look whether there is a mdraid 0.90 superblock. */ + if (sb.md_magic == SB_MAGIC) + goto superblock_0_90; + + /* Check for an 1.x superblock. + * It's always aligned to a 4K boundary + * and depending on the minor version it can be: + * 0: At least 8K, but less than 12K, from end of device + * 1: At start of device + * 2: 4K from start of device. + */ + + sb_1x = grub_malloc (sizeof (struct grub_raid_super_1x)); + if (!sb_1x) + return grub_errno; + + for (minor_version = 0; minor_version < 3; ++minor_version) + { + switch (minor_version) + { + case 0: + sector = (size - 8 * 2) & ~(4 * 2 - 1); + break; + case 1: + sector = 0; + break; + case 2: + sector = 4 * 2; + break; + } + + if (grub_disk_read + (disk, sector, 0, sizeof (struct grub_raid_super_1x), sb_1x)) + { + grub_free (sb_1x); + return grub_errno; + } + + if (sb_1x->magic == SB_MAGIC) + goto superblock_1_x; + } + + /* Neither 0.90 nor 1.x. */ + if (grub_le_to_cpu32 (sb_1x->magic) != SB_MAGIC) return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); - /* FIXME: Also support version 1.0. */ +superblock_0_90: + 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. */ + /* FIXME: Check the checksum. */ /* Multipath. */ if ((int) sb.level == -4) @@ -195,6 +309,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported RAID level: %d", sb.level); + array->name = NULL; array->number = sb.md_minor; array->level = sb.level; array->layout = sb.layout; @@ -205,7 +320,10 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) array->uuid_len = 16; array->uuid = grub_malloc (16); if (!array->uuid) - return grub_errno; + { + grub_free (sb_1x); + return grub_errno; + } uuid = (grub_uint32_t *) array->uuid; uuid[0] = sb.set_uuid0; @@ -214,6 +332,63 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) uuid[3] = sb.set_uuid3; return 0; + + superblock_1_x: + + if (sb_1x->major_version != 1) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID version: %d", + sb_1x->major_version); + /* Multipath. */ + if ((int) sb_1x->level == -4) + sb_1x->level = 1; + + if (sb_1x->level != 0 && sb_1x->level != 1 && sb_1x->level != 4 && + sb_1x->level != 5 && sb_1x->level != 6 && sb_1x->level != 10) + { + grub_free (sb_1x); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID level: %d", sb.level); + } + /* 1.x superblocks don't have a fixed size on disk. So we have to + read it again now that we now the max device count. */ + sb_size = sizeof (struct grub_raid_super_1x) + 2 * grub_le_to_cpu32 (sb_1x->max_dev); + sb_1x = grub_realloc (sb_1x, sb_size); + if (! sb_1x) + return grub_errno; + + if (grub_disk_read (disk, sector, 0, sb_size, sb_1x)) + { + grub_free (sb_1x); + return grub_errno; + } + + array->name = grub_strdup (sb_1x->set_name); + if (! array->name) + { + grub_free (sb_1x); + return grub_errno; + } + + array->number = 0; + array->level = grub_le_to_cpu32 (sb_1x->level); + array->layout = grub_le_to_cpu32 (sb_1x->layout); + array->total_devs = grub_le_to_cpu32 (sb_1x->raid_disks); + array->disk_size = grub_le_to_cpu64 (sb_1x->size) * 2; + array->chunk_size = grub_le_to_cpu32 (sb_1x->chunksize) >> 9; + array->index = grub_le_to_cpu32 (sb_1x->dev_number); + array->uuid_len = 16; + array->uuid = grub_malloc (16); + if (!array->uuid) + { + grub_free (sb_1x); + return grub_errno; + } + + grub_memcpy (array->uuid, sb_1x->set_uuid, 16); + + grub_free (sb_1x); + return 0; } static struct grub_raid grub_mdraid_dev = { diff --git a/disk/raid.c b/disk/raid.c index c720fb36c..b88741744 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -1,7 +1,7 @@ /* raid.c - module to read RAID arrays. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * 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 @@ -480,7 +480,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, struct grub_raid_array *array = 0, *p; /* See whether the device is part of an array we have already seen a - device from. */ + 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))) @@ -491,7 +491,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* Do some checks before adding the device to the array. */ /* FIXME: Check whether the update time of the superblocks are - the same. */ + the same. */ if (array->total_devs == array->nr_devs) /* We found more members of the array than the array @@ -502,7 +502,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, if (array->device[new_array->index] != NULL) /* We found multiple devices with the same number. Again, - this shouldn't happen.*/ + this shouldn't happen. */ grub_dprintf ("raid", "Found two disks with the number %d?!?", new_array->number); @@ -525,47 +525,55 @@ insert_array (grub_disk_t disk, struct grub_raid_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. */ + if (array->name) + goto skip_duplicate_check; + /* 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->number == array->number) + break; } if (p) { - /* The number is already in use, so we need to find an new number. */ + /* The number is already in use, so we need to find a new one. */ int i = 0; - while (1) - { - for (p = array_list; p != NULL; p = p->next) - { - if (p->number == i) - break; - } + 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; - } + if (! p) + { + /* We found an unused number. */ + array->number = i; + break; + } - i++; - } - } - - array->name = grub_malloc (13); + i++; + } + } + skip_duplicate_check: + /* mdraid 1.x superblocks have only a name stored not a number. + Use it directly as GRUB device. */ if (! array->name) - { - grub_free (array->uuid); - grub_free (array); + { + 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); + return grub_errno; + } + grub_sprintf (array->name, "md%d", array->number); + } + else + grub_sprintf (array->name, "%s", array->name); grub_dprintf ("raid", "Found array %s (%s)\n", array->name, scanner_name); diff --git a/util/getroot.c b/util/getroot.c index 120ab13b1..618d76158 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -498,6 +498,20 @@ grub_util_get_grub_dev (const char *os_dev) asprintf (&grub_dev, "md%s", p); free (p); } + else if (os_dev[7] == '/') + { + /* mdraid 1.x with a free name. */ + char *p , *q; + + p = strdup (os_dev + sizeof ("/dev/md/") - 1); + + q = strchr (p, 'p'); + if (q) + *q = ','; + + asprintf (&grub_dev, "%s", p); + free (p); + } else grub_util_error ("Unknown kind of RAID device `%s'", os_dev); From c6622adb31fc8666a2cfe07fc6f44cd82eec3585 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Wed, 11 Nov 2009 23:17:59 +0100 Subject: [PATCH 002/503] make autogen.sh and gendistlist.sh executable --- autogen.sh | 0 gendistlist.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 autogen.sh mode change 100644 => 100755 gendistlist.sh diff --git a/autogen.sh b/autogen.sh old mode 100644 new mode 100755 diff --git a/gendistlist.sh b/gendistlist.sh old mode 100644 new mode 100755 From 4e962809b57b5018e00ca982d55a012c6e6674d7 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Mon, 16 Nov 2009 21:46:43 +0100 Subject: [PATCH 003/503] 2009-11-16 Felix Zielcke * disk/mdraid_linux.c: Fix the unsupported RAID version error with metadata 1.x. --- ChangeLog.raid | 5 +++++ disk/mdraid_linux.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog.raid b/ChangeLog.raid index 090e1edc7..645f7e7f1 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,8 @@ +2009-11-16 Felix Zielcke + + * disk/mdraid_linux.c: Fix the unsupported RAID version error + with metadata 1.x. + 2009-11-06 Felix Zielcke * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Set array->name to NULL. diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index 275267f72..026adb380 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -346,9 +346,9 @@ superblock_0_90: if (sb_1x->level != 0 && sb_1x->level != 1 && sb_1x->level != 4 && sb_1x->level != 5 && sb_1x->level != 6 && sb_1x->level != 10) { - grub_free (sb_1x); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID level: %d", sb.level); + "Unsupported RAID level: %d", sb_1x->level); + grub_free (sb_1x); } /* 1.x superblocks don't have a fixed size on disk. So we have to read it again now that we now the max device count. */ From 8bcaed961a8e08081c22a511c70c1fdddfa297a3 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Mon, 16 Nov 2009 21:52:10 +0100 Subject: [PATCH 004/503] 2009-11-16 Felix Zielcke * disk/mdraid_linux.c (grub_mdraid_detect): Remove a wrong call of free(). --- ChangeLog.raid | 9 +++++++-- disk/mdraid_linux.c | 3 --- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog.raid b/ChangeLog.raid index 645f7e7f1..854702f41 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,7 +1,12 @@ 2009-11-16 Felix Zielcke - * disk/mdraid_linux.c: Fix the unsupported RAID version error - with metadata 1.x. + * disk/mdraid_linux.c (grub_mdraid_detect): Remove a wrong call + of free(). + +2009-11-16 Felix Zielcke + + * disk/mdraid_linux.c (grub_mdraid_detect): Fix the unsupported + RAID version error with metadata 1.x. 2009-11-06 Felix Zielcke diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index 026adb380..8670710b3 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -320,10 +320,7 @@ superblock_0_90: array->uuid_len = 16; array->uuid = grub_malloc (16); if (!array->uuid) - { - grub_free (sb_1x); return grub_errno; - } uuid = (grub_uint32_t *) array->uuid; uuid[0] = sb.set_uuid0; From acdf01cd1b5780152ce79f4dcce28dbe94fe2a8a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Dec 2009 21:28:27 +0100 Subject: [PATCH 005/503] cmostest command --- commands/i386/cmostest.c | 59 ++++++++++++++++++++++++++++++++++++++++ conf/i386-coreboot.rmk | 6 ++++ conf/i386-pc.rmk | 6 ++++ 3 files changed, 71 insertions(+) create mode 100644 commands/i386/cmostest.c diff --git a/commands/i386/cmostest.c b/commands/i386/cmostest.c new file mode 100644 index 000000000..7171766cd --- /dev/null +++ b/commands/i386/cmostest.c @@ -0,0 +1,59 @@ +/* + * 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 + +static grub_err_t +grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int byte, bit; + char *rest; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); + + byte = grub_strtoul (argv[0], &rest, 0); + if (*rest != ':') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); + + bit = grub_strtoul (rest + 1, 0, 0); + + if (grub_cmos_read (byte) & (1 << bit)) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_TEST_FAILURE, "false"); +} + +static grub_command_t cmd; + + +GRUB_MOD_INIT(cmostest) +{ + cmd = grub_register_command ("cmostest", grub_cmd_cmostest, + "cmostest BYTE:BIT", + "Test bit at BYTE:BIT in CMOS."); +} + +GRUB_MOD_FINI(cmostest) +{ + grub_unregister_command (cmd); +} diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index e597328e7..b49af84ce 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -202,5 +202,11 @@ lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cmostest.mod +pkglib_MODULES += cmostest.mod +cmostest_mod_SOURCES = commands/i386/cmostest.c +cmostest_mod_CFLAGS = $(COMMON_CFLAGS) +cmostest_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 index 7e54b3b67..8d373e30b 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -335,6 +335,12 @@ hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c hdparm_mod_CFLAGS = $(COMMON_CFLAGS) hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cmostest.mod +pkglib_MODULES += cmostest.mod +cmostest_mod_SOURCES = commands/i386/cmostest.c +cmostest_mod_CFLAGS = $(COMMON_CFLAGS) +cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS) + ifeq ($(enable_efiemu), yes) efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) From b044bf0351fe2dda87e6072133d41c339715452c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 16 Dec 2009 19:04:58 +0100 Subject: [PATCH 006/503] use video subsystem on EFI --- conf/i386-efi.rmk | 2 +- conf/i386-pc.rmk | 2 +- conf/x86_64-efi.rmk | 2 +- include/grub/i386/xnu.h | 1 - loader/i386/efi/linux.c | 277 +++++++++++++++------------------------- loader/i386/efi/xnu.c | 178 -------------------------- loader/i386/pc/xnu.c | 108 ---------------- loader/i386/xnu.c | 83 ++++++++++++ 8 files changed, 190 insertions(+), 463 deletions(-) delete mode 100644 loader/i386/efi/xnu.c delete mode 100644 loader/i386/pc/xnu.c diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 629b83999..a037ed383 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -154,7 +154,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS) efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \ loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 031c24adf..b71a7edc0 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -183,7 +183,7 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c\ +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \ loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index ee511e1bd..6db52f480 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -160,7 +160,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS) efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \ loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h index 306dc7b65..ea2767a79 100644 --- a/include/grub/i386/xnu.h +++ b/include/grub/i386/xnu.h @@ -76,6 +76,5 @@ extern grub_uint32_t grub_xnu_arg1; extern char grub_xnu_cmdline[1024]; grub_err_t grub_xnu_boot (void); grub_err_t grub_cpu_xnu_fill_devicetree (void); -grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc); extern grub_uint32_t grub_xnu_heap_will_be_at; #endif diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 8cd4d23f2..3b066d589 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -29,10 +29,11 @@ #include #include #include -#include -#include #include #include +#include +#include +#include #define GRUB_LINUX_CL_OFFSET 0x1000 #define GRUB_LINUX_CL_END_OFFSET 0x2000 @@ -285,6 +286,66 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, } } +static grub_err_t +grub_linux_setup_video (struct linux_kernel_params *params) +{ + struct grub_video_mode_info mode_info; + void *framebuffer; + grub_err_t err; + + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); + + if (err) + return err; + + params->lfb_width = mode_info.width; + params->lfb_height = mode_info.height; + params->lfb_depth = mode_info.bpp; + params->lfb_line_len = mode_info.pitch; + + params->lfb_base = (grub_size_t) framebuffer; + params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16; + + params->red_mask_size = mode_info.red_mask_size; + params->red_field_pos = mode_info.red_field_pos; + params->green_mask_size = mode_info.green_mask_size; + params->green_field_pos = mode_info.green_field_pos; + params->blue_mask_size = mode_info.blue_mask_size; + params->blue_field_pos = mode_info.blue_field_pos; + params->reserved_mask_size = mode_info.reserved_mask_size; + params->reserved_field_pos = mode_info.reserved_field_pos; + + params->have_vga = GRUB_VIDEO_TYPE_EFI; + +#ifdef GRUB_MACHINE_PCBIOS + /* VESA packed modes may come with zeroed mask sizes, which need + to be set here according to DAC Palette width. If we don't, + this results in Linux displaying a black screen. */ + if (mode_info.bpp <= 8) + { + struct grub_vbe_info_block controller_info; + int status; + int width = 8; + + status = grub_vbe_bios_get_controller_info (&controller_info); + + if (status == GRUB_VBE_STATUS_OK && + (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH)) + status = grub_vbe_bios_set_dac_palette_width (&width); + + if (status != GRUB_VBE_STATUS_OK) + /* 6 is default after mode reset. */ + width = 6; + + params->red_mask_size = params->green_mask_size + = params->blue_mask_size = width; + params->reserved_mask_size = 0; + } +#endif + + return 0; +} + #ifdef __x86_64__ extern grub_uint8_t grub_linux_trampoline_start[]; extern grub_uint8_t grub_linux_trampoline_end[]; @@ -299,9 +360,14 @@ grub_linux_boot (void) grub_efi_uintn_t desc_size; grub_efi_uint32_t desc_version; int e820_num; + const char *modevar; + char *tmp; + grub_err_t err; params = real_mode_mem; + grub_printf ("%d\n", __LINE__); + grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n", (unsigned) params->code32_start, (unsigned long) &(idt_desc.limit), @@ -310,6 +376,8 @@ grub_linux_boot (void) (unsigned) idt_desc.limit, (unsigned long) idt_desc.base, (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base); + grub_printf ("%d\n", __LINE__); + 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) { @@ -348,10 +416,43 @@ grub_linux_boot (void) return 0; } + grub_printf ("%d\n", __LINE__); + e820_num = 0; grub_mmap_iterate (hook); params->mmap_size = e820_num; + modevar = grub_env_get ("gfxpayload"); + + /* Now all graphical modes are acceptable. + May change in future if we have modes without framebuffer. */ + if (modevar && *modevar != 0) + { + tmp = grub_malloc (grub_strlen (modevar) + + sizeof (";auto")); + if (! tmp) + return grub_errno; + grub_sprintf (tmp, "%s;auto", modevar); + err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); + grub_free (tmp); + } + else + err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); + + grub_printf ("Trampoline at %p. code32=%x, real_mode_mem=%p\n", + ((char *) prot_mode_mem + (prot_mode_pages << 12)), + (unsigned) params->code32_start, real_mode_mem); + + if (!err) + err = grub_linux_setup_video (params); + + if (err) + { + grub_print_error (); + grub_printf ("Booting however\n"); + grub_errno = GRUB_ERR_NONE; + } + mmap_size = find_mmap_size (); if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, &desc_size, &desc_version) <= 0) @@ -424,174 +525,6 @@ grub_linux_unload (void) return GRUB_ERR_NONE; } -static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; - - -#define RGB_MASK 0xffffff -#define RGB_MAGIC 0x121314 -#define LINE_MIN 800 -#define LINE_MAX 4096 -#define FBTEST_STEP (0x10000 >> 2) -#define FBTEST_COUNT 8 - -static int -find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) -{ - grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base; - int i; - - for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP) - { - if ((*base & RGB_MASK) == RGB_MAGIC) - { - int j; - - for (j = LINE_MIN; j <= LINE_MAX; j++) - { - if ((base[j] & RGB_MASK) == RGB_MAGIC) - { - *fb_base = (grub_uint32_t) (grub_target_addr_t) base; - *line_len = j << 2; - - return 1; - } - } - - break; - } - } - - return 0; -} - -static int -find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) -{ - int found = 0; - - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid); - - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid) - { - grub_pci_address_t addr; - - addr = grub_pci_make_address (dev, 2); - if (grub_pci_read (addr) >> 24 == 0x3) - { - int i; - - grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n", - grub_pci_get_bus (dev), grub_pci_get_device (dev), - grub_pci_get_function (dev), pciid); - addr += 8; - for (i = 0; i < 6; i++, addr += 4) - { - grub_uint32_t old_bar1, old_bar2, type; - grub_uint64_t base64; - - old_bar1 = grub_pci_read (addr); - if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO)) - continue; - - type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK; - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - if (i == 5) - break; - - old_bar2 = grub_pci_read (addr + 4); - } - else - old_bar2 = 0; - - base64 = old_bar2; - base64 <<= 32; - base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); - - grub_printf ("%s(%d): 0x%llx\n", - ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? - "VMEM" : "MMIO"), i, - (unsigned long long) base64); - - if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found)) - { - *fb_base = base64; - if (find_line_len (fb_base, line_len)) - found++; - } - - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - i++; - addr += 4; - } - } - } - - return found; - } - - grub_pci_iterate (find_card); - return found; -} - -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, pixel, fb_base, line_len; - int ret; - - 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); - - grub_efi_set_text_mode (0); - pixel = RGB_MAGIC; - efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel, - GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0); - ret = find_framebuf (&fb_base, &line_len); - grub_efi_set_text_mode (1); - - if (! ret) - { - grub_printf ("Can\'t find frame buffer address\n"); - return 1; - } - - grub_printf ("Frame buffer base: 0x%x\n", fb_base); - grub_printf ("Video line length: %d\n", line_len); - - params->lfb_width = width; - params->lfb_height = height; - params->lfb_depth = depth; - params->lfb_line_len = line_len; - - params->lfb_base = fb_base; - params->lfb_size = (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; - - params->have_vga = GRUB_VIDEO_TYPE_VLFB; - params->vid_mode = 0x338; /* 1024x768x32 */ - - return 0; -} - static grub_err_t grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) @@ -790,8 +723,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_printf (" [Linux-bzImage, setup=0x%x, size=0x%x]\n", (unsigned) real_size, (unsigned) prot_size); - grub_linux_setup_video (params); - /* Detect explicitly specified memory size, if any. */ linux_mem_size = 0; for (i = 1; i < argc; i++) @@ -857,7 +788,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (grub_errno == GRUB_ERR_NONE) { - grub_loader_set (grub_linux_boot, grub_linux_unload, 1); + grub_loader_set (grub_linux_boot, grub_linux_unload, 0); loaded = 1; } diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c deleted file mode 100644 index 236732804..000000000 --- a/loader/i386/efi/xnu.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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 - -/* Setup video for xnu. Big parts are copied from linux.c. */ - -static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; - -#define RGB_MASK 0xffffff -#define RGB_MAGIC 0x121314 -#define LINE_MIN 800 -#define LINE_MAX 4096 -#define FBTEST_STEP (0x10000 >> 2) -#define FBTEST_COUNT 8 - -static int -find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) -{ - grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base; - int i; - - for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP) - { - if ((*base & RGB_MASK) == RGB_MAGIC) - { - int j; - - for (j = LINE_MIN; j <= LINE_MAX; j++) - { - if ((base[j] & RGB_MASK) == RGB_MAGIC) - { - *fb_base = (grub_uint32_t) (grub_target_addr_t) base; - *line_len = j << 2; - - return 1; - } - } - - break; - } - } - - return 0; -} - -static int -find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) -{ - int found = 0; - - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid); - - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid) - { - grub_pci_address_t addr; - - addr = grub_pci_make_address (dev, 2); - if (grub_pci_read (addr) >> 24 == 0x3) - { - int i; - - grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n", - grub_pci_get_bus (dev), grub_pci_get_device (dev), - grub_pci_get_function (dev), pciid); - addr += 8; - for (i = 0; i < 6; i++, addr += 4) - { - grub_uint32_t old_bar1, old_bar2, type; - grub_uint64_t base64; - - old_bar1 = grub_pci_read (addr); - if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO)) - continue; - - type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK; - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - if (i == 5) - break; - - old_bar2 = grub_pci_read (addr + 4); - } - else - old_bar2 = 0; - - base64 = old_bar2; - base64 <<= 32; - base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); - - grub_printf ("%s(%d): 0x%llx\n", - ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? - "VMEM" : "MMIO"), i, - (unsigned long long) base64); - - if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found)) - { - *fb_base = base64; - if (find_line_len (fb_base, line_len)) - found++; - } - - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - i++; - addr += 4; - } - } - } - - return found; - } - - grub_pci_iterate (find_card); - return found; -} - -grub_err_t -grub_xnu_set_video (struct grub_xnu_boot_params *params) -{ - grub_efi_uga_draw_protocol_t *c; - grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len; - int ret; - - c = grub_efi_locate_protocol (&uga_draw_guid, 0); - if (! c) - return grub_error (GRUB_ERR_IO, "Couldn't find UGADraw"); - - if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate)) - return grub_error (GRUB_ERR_IO, "Couldn't retrieve video mode"); - - grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate); - - grub_efi_set_text_mode (0); - pixel = RGB_MAGIC; - efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel, - GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0); - ret = find_framebuf (&fb_base, &line_len); - grub_efi_set_text_mode (1); - - if (! ret) - return grub_error (GRUB_ERR_IO, "Can\'t find frame buffer address\n"); - - grub_printf ("Frame buffer base: 0x%x\n", fb_base); - grub_printf ("Video line length: %d\n", line_len); - - params->lfb_width = width; - params->lfb_height = height; - params->lfb_depth = depth; - params->lfb_line_len = line_len; - params->lfb_mode = GRUB_XNU_VIDEO_TEXT_IN_VIDEO; - params->lfb_base = fb_base; - return GRUB_ERR_NONE; -} diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c deleted file mode 100644 index 839d0ad44..000000000 --- a/loader/i386/pc/xnu.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 - -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#define max(a,b) (((a) > (b)) ? (a) : (b)) - -#define DEFAULT_VIDEO_MODE "auto" - -/* Setup video for xnu. */ -grub_err_t -grub_xnu_set_video (struct grub_xnu_boot_params *params) -{ - struct grub_video_mode_info mode_info; - int ret; - char *tmp, *modevar; - void *framebuffer; - grub_err_t err; - - modevar = grub_env_get ("gfxpayload"); - /* Consider only graphical 32-bit deep modes. */ - if (! modevar || *modevar == 0) - err = grub_video_set_mode (DEFAULT_VIDEO_MODE, - GRUB_VIDEO_MODE_TYPE_PURE_TEXT - | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK, - 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS); - else - { - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (DEFAULT_VIDEO_MODE) + 1); - if (! tmp) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "couldn't allocate temporary storag"); - grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); - err = grub_video_set_mode (tmp, - GRUB_VIDEO_MODE_TYPE_PURE_TEXT - | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK, - 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS); - grub_free (tmp); - } - - if (err) - return err; - - if (grub_xnu_bitmap) - { - int x, y; - - x = mode_info.width - grub_xnu_bitmap->mode_info.width; - x /= 2; - y = mode_info.height - grub_xnu_bitmap->mode_info.height; - y /= 2; - err = grub_video_blit_bitmap (grub_xnu_bitmap, - GRUB_VIDEO_BLIT_REPLACE, - x > 0 ? x : 0, - y > 0 ? y : 0, - x < 0 ? -x : 0, - y < 0 ? -y : 0, - min (grub_xnu_bitmap->mode_info.width, - mode_info.width), - min (grub_xnu_bitmap->mode_info.height, - mode_info.height)); - if (err) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - grub_xnu_bitmap = 0; - } - err = GRUB_ERR_NONE; - } - - ret = grub_video_get_info_and_fini (&mode_info, &framebuffer); - if (ret) - return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters"); - - params->lfb_width = mode_info.width; - params->lfb_height = mode_info.height; - params->lfb_depth = mode_info.bpp; - params->lfb_line_len = mode_info.pitch; - - params->lfb_base = PTR_TO_UINT32 (framebuffer); - params->lfb_mode = grub_xnu_bitmap - ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO; - - return GRUB_ERR_NONE; -} - diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 6a3535950..23fbbe7e0 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -29,6 +29,11 @@ #include #include +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define max(a,b) (((a) > (b)) ? (a) : (b)) + +#define DEFAULT_VIDEO_MODE "auto" + char grub_xnu_cmdline[1024]; grub_uint32_t grub_xnu_heap_will_be_at; grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack; @@ -417,6 +422,84 @@ grub_xnu_boot_resume (void) state); } +/* Setup video for xnu. */ +static grub_err_t +grub_xnu_set_video (struct grub_xnu_boot_params *params) +{ + struct grub_video_mode_info mode_info; + int ret; + char *tmp, *modevar; + void *framebuffer; + grub_err_t err; + + modevar = grub_env_get ("gfxpayload"); + /* Consider only graphical 32-bit deep modes. */ + if (! modevar || *modevar == 0) + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT + | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK, + 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS); + else + { + tmp = grub_malloc (grub_strlen (modevar) + + sizeof (DEFAULT_VIDEO_MODE) + 1); + if (! tmp) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate temporary storag"); + grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); + err = grub_video_set_mode (tmp, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT + | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK, + 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS); + grub_free (tmp); + } + + if (err) + return err; + + if (grub_xnu_bitmap) + { + int x, y; + + x = mode_info.width - grub_xnu_bitmap->mode_info.width; + x /= 2; + y = mode_info.height - grub_xnu_bitmap->mode_info.height; + y /= 2; + err = grub_video_blit_bitmap (grub_xnu_bitmap, + GRUB_VIDEO_BLIT_REPLACE, + x > 0 ? x : 0, + y > 0 ? y : 0, + x < 0 ? -x : 0, + y < 0 ? -y : 0, + min (grub_xnu_bitmap->mode_info.width, + mode_info.width), + min (grub_xnu_bitmap->mode_info.height, + mode_info.height)); + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + grub_xnu_bitmap = 0; + } + err = GRUB_ERR_NONE; + } + + ret = grub_video_get_info_and_fini (&mode_info, &framebuffer); + if (ret) + return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters"); + + params->lfb_width = mode_info.width; + params->lfb_height = mode_info.height; + params->lfb_depth = mode_info.bpp; + params->lfb_line_len = mode_info.pitch; + + params->lfb_base = PTR_TO_UINT32 (framebuffer); + params->lfb_mode = grub_xnu_bitmap + ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO; + + return GRUB_ERR_NONE; +} + /* Boot xnu. */ grub_err_t grub_xnu_boot (void) From 289634b1fa937dd5011d2513d05b9b065090b3c6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 11:15:46 +0100 Subject: [PATCH 007/503] Report trampoline information before going to video mode --- loader/i386/efi/linux.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 3b066d589..5870edb4b 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -422,6 +422,10 @@ grub_linux_boot (void) grub_mmap_iterate (hook); params->mmap_size = e820_num; + grub_printf ("Trampoline at %p. code32=%x, real_mode_mem=%p\n", + ((char *) prot_mode_mem + (prot_mode_pages << 12)), + (unsigned) params->code32_start, real_mode_mem); + modevar = grub_env_get ("gfxpayload"); /* Now all graphical modes are acceptable. @@ -439,10 +443,6 @@ grub_linux_boot (void) else err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); - grub_printf ("Trampoline at %p. code32=%x, real_mode_mem=%p\n", - ((char *) prot_mode_mem + (prot_mode_pages << 12)), - (unsigned) params->code32_start, real_mode_mem); - if (!err) err = grub_linux_setup_video (params); From 51bd7ea32acf7349d72ce61cfa9f93f7486f9723 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Fri, 18 Dec 2009 20:57:22 +0100 Subject: [PATCH 008/503] Set correct chunksize with metadata 1.x --- disk/mdraid_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index 8670710b3..79363d143 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -372,7 +372,7 @@ superblock_0_90: array->layout = grub_le_to_cpu32 (sb_1x->layout); array->total_devs = grub_le_to_cpu32 (sb_1x->raid_disks); array->disk_size = grub_le_to_cpu64 (sb_1x->size) * 2; - array->chunk_size = grub_le_to_cpu32 (sb_1x->chunksize) >> 9; + array->chunk_size = grub_le_to_cpu32 (sb_1x->chunksize); array->index = grub_le_to_cpu32 (sb_1x->dev_number); array->uuid_len = 16; array->uuid = grub_malloc (16); From ac0289ba9269f9acc776b0ba7b4ad38134dfcedc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 11:24:13 +0100 Subject: [PATCH 009/503] grub-mkrescue for EFI (untested) --- conf/common.rmk | 6 ++++++ conf/i386-coreboot.rmk | 7 +------ conf/i386-efi.rmk | 3 +++ conf/i386-ieee1275.rmk | 7 +------ conf/i386-pc.rmk | 7 +------ conf/powerpc-ieee1275.rmk | 6 ------ conf/sparc64-ieee1275.rmk | 6 ------ conf/x86_64-efi.rmk | 3 +++ util/grub-mkrescue.in | 35 ++++++++++++++++++++++++++++++++--- 9 files changed, 47 insertions(+), 33 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 896705526..a961e502a 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -632,3 +632,9 @@ pkglib_MODULES += setjmp.mod setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +pkglib_MODULES += memdisk.mod +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index ccc326f5c..439e462c5 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -102,7 +102,7 @@ grub_mkrescue_SOURCES = util/grub-mkrescue.in # Modules. pkglib_MODULES = linux.mod multiboot.mod \ aout.mod play.mod serial.mod \ - memdisk.mod pci.mod lspci.mod reboot.mod \ + pci.mod lspci.mod reboot.mod \ halt.mod datetime.mod date.mod datehook.mod \ lsmmap.mod mmap.mod @@ -165,11 +165,6 @@ play_mod_SOURCES = commands/i386/pc/play.c play_mod_CFLAGS = $(COMMON_CFLAGS) play_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) diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index c135ded4e..e55d7c95a 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -15,6 +15,9 @@ grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + # 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 \ diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 8d9577844..78a100c1a 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -56,7 +56,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in # Modules. pkglib_MODULES = halt.mod reboot.mod suspend.mod \ aout.mod serial.mod linux.mod \ - nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ + nand.mod pci.mod lspci.mod datetime.mod \ date.mod datehook.mod lsmmap.mod mmap.mod # For boot.mod. @@ -106,11 +106,6 @@ 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) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 7e54b3b67..b682aad94 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -121,7 +121,7 @@ grub_mkfloppy_SOURCES = util/i386/pc/grub-mkfloppy.in pkglib_MODULES = biosdisk.mod chain.mod \ multiboot.mod reboot.mod halt.mod \ vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \ - vga.mod memdisk.mod pci.mod lspci.mod \ + vga.mod pci.mod lspci.mod \ aout.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 \ @@ -239,11 +239,6 @@ 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) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 85b1fa211..0b5b03c5d 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -62,7 +62,6 @@ pkglib_MODULES = halt.mod \ reboot.mod \ suspend.mod \ multiboot.mod \ - memdisk.mod \ lsmmap.mod # For boot.mod. @@ -98,11 +97,6 @@ multiboot_mod_SOURCES = loader/ieee1275/multiboot2.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) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 8c8bf27e6..dc845e1a5 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -99,7 +99,6 @@ grub_install_SOURCES = util/sparc64/ieee1275/grub-install.in pkglib_MODULES = halt.mod \ linux.mod \ reboot.mod \ - memdisk.mod \ lsmmap.mod # For boot.mod. @@ -123,11 +122,6 @@ halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_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) diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 22ed2d639..2de6ab443 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -14,6 +14,9 @@ bin_UTILITIES = grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ util/misc.c util/resolve.c +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + # 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 \ diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 51639ccb1..30f319dc3 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -31,6 +31,8 @@ native_platform=@platform@ coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-coreboot pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc +efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi +efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi # Usage: usage # Print the usage. @@ -109,13 +111,23 @@ if [ "${override_dir}" = "" ] ; then if test -e "${pc_dir}" ; then process_input_dir ${pc_dir} pc fi + if test -e "${efi32_dir}" ; then + process_input_dir ${efi32_dir} efi32 + fi + if test -e "${efi64_dir}" ; then + process_input_dir ${efi64_dir} efi64 + fi else process_input_dir ${override_dir} ${native_platform} coreboot_dir= pc_dir= - case "${native_platform}" in - coreboot) coreboot_dir=${override_dir} ;; - pc) pc_dir=${override_dir} ;; + efi32_dir= + efi64_dir= + case "${target_cpu}-${native_platform}" in + i386-coreboot) coreboot_dir=${override_dir} ;; + i386-pc) pc_dir=${override_dir} ;; + i386-efi) efi32_dir=${override_dir} ;; + x86_64-efi) efi64_dir=${override_dir} ;; esac fi @@ -168,6 +180,23 @@ if test -e "${pc_dir}" ; then grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -boot-info-table" fi +# build bootx64.efi +if test -e "${efi64_dir}" ; then + echo "Generates bootx64.efi" + mkdir -p ${iso9660_dir}/efi/boot + grub-mkimage -d ${efi64_dir}/ -o ${iso9660_dir}/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ + search iso9660 configfile sh + + modules="$(cat ${efi64_dir}/partmap.lst) ${modules}" + (for i in ${modules} ; do + if [ "x$i" != xkernel.mod ]; then + echo "insmod $i" + fi + done ; \ + echo "source /boot/grub/grub.cfg") \ + > ${iso9660_dir}/boot/grub/x86_64-efi/grub.cfg +fi + # build iso image grub-mkisofs ${grub_mkisofs_arguments} -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} From f0cfb703b8b1f5312cb5700a0b9b3c293f76f9d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jan 2010 20:37:16 +0100 Subject: [PATCH 010/503] Initial bidi support for gfxmenu --- autogen.sh | 2 + conf/common.rmk | 2 +- font/font.c | 375 +- include/grub/bidi.h | 60 + unidata.c | 458 + util/UnicodeData.txt | 19336 +++++++++++++++++++++++++++++++++++++++++ util/import_bidi.py | 52 + 7 files changed, 20279 insertions(+), 6 deletions(-) create mode 100644 include/grub/bidi.h create mode 100644 unidata.c create mode 100644 util/UnicodeData.txt create mode 100644 util/import_bidi.py diff --git a/autogen.sh b/autogen.sh index eb251f9f0..7aac1c534 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,6 +13,8 @@ echo timestamp > stamp-h.in python util/import_gcry.py lib/libgcrypt/ . +python util/import_bidi.py util/UnicodeData.txt unidata.c + for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do if test -e $rmk ; then ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'` diff --git a/conf/common.rmk b/conf/common.rmk index 93b138eee..512288614 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -642,7 +642,7 @@ 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_SOURCES = font/font_cmd.c font/font.c unidata.c font_mod_CFLAGS = $(COMMON_CFLAGS) font_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/font/font.c b/font/font.c index 12f80847f..8823bc6d3 100644 --- a/font/font.c +++ b/font/font.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #ifndef FONT_DEBUG #define FONT_DEBUG 0 @@ -1045,6 +1047,359 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, glyph->width, glyph->height); } +static inline enum grub_bidi_type +get_bidi_type (grub_uint32_t c) +{ + static grub_uint8_t *bidi_types = NULL; + struct grub_bidi_compact_range *cur; + + if (!bidi_types) + { + unsigned i; + bidi_types = grub_zalloc (GRUB_BIDI_MAX_CACHED_UNICODE_CHAR); + if (bidi_types) + for (cur = grub_bidi_compact; cur->end; cur++) + for (i = cur->start; i <= cur->end + && i < GRUB_BIDI_MAX_CACHED_UNICODE_CHAR; i++) + bidi_types[i] = cur->type; + else + grub_errno = GRUB_ERR_NONE; + } + + if (bidi_types && c < GRUB_BIDI_MAX_CACHED_UNICODE_CHAR) + return bidi_types[c]; + + for (cur = grub_bidi_compact; cur->end; cur++) + if (cur->start <= c && c <= cur->end) + return cur->type; + + return GRUB_BIDI_TYPE_L; +} + +static grub_ssize_t +grub_err_bidi_logical_to_visual (grub_uint32_t *logical, + grub_size_t logical_len, + grub_uint32_t **visual) +{ + enum grub_bidi_type type = GRUB_BIDI_TYPE_L; + enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; + unsigned *levels; + enum grub_bidi_type *resolved_types; + unsigned base_level; + enum override_status cur_override; + unsigned i; + unsigned stack_level[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; + enum override_status stack_override[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; + unsigned stack_depth = 0; + unsigned invalid_pushes = 0; + unsigned no_markers_len = 0; + unsigned run_start, run_end; + grub_uint32_t *no_markers; + unsigned cur_level; + + auto void push_stack (unsigned new_override, unsigned new_level); + void push_stack (unsigned new_override, unsigned new_level) + { + if (new_level > GRUB_BIDI_MAX_EXPLICIT_LEVEL) + { + invalid_pushes++; + return; + } + stack_level[stack_depth] = cur_level; + stack_override[stack_depth] = cur_override; + stack_depth++; + cur_level = new_level; + cur_override = new_override; + } + + auto void pop_stack (void); + void pop_stack (void) + { + if (invalid_pushes) + { + invalid_pushes--; + return; + } + if (!stack_depth) + return; + stack_depth--; + cur_level = stack_level[stack_depth]; + cur_override = stack_override[stack_depth]; + } + + auto void revert (unsigned start, unsigned end); + void revert (unsigned start, unsigned end) + { + grub_uint32_t t; + unsigned k; + for (k = 0; k <= (end - start) / 2; k++) + { + t = no_markers[start+k]; + no_markers[start+k] = no_markers[end-k]; + no_markers[end-k] = t; + } + } + + levels = grub_malloc (sizeof (levels[0]) * logical_len); + if (!levels) + return -1; + + resolved_types = grub_malloc (sizeof (resolved_types[0]) * logical_len); + if (!resolved_types) + { + grub_free (levels); + return -1; + } + + no_markers = grub_malloc (sizeof (resolved_types[0]) * logical_len); + if (!no_markers) + { + grub_free (resolved_types); + grub_free (levels); + return -1; + } + + for (i = 0; i < logical_len; i++) + { + type = get_bidi_type (logical[i]); + if (type == GRUB_BIDI_TYPE_L || type == GRUB_BIDI_TYPE_AL + || type == GRUB_BIDI_TYPE_R) + break; + } + if (type == GRUB_BIDI_TYPE_R || type == GRUB_BIDI_TYPE_AL) + base_level = 1; + else + base_level = 0; + + cur_level = base_level; + cur_override = OVERRIDE_NEUTRAL; + for (i = 0; i < logical_len; i++) + { + type = get_bidi_type (logical[i]); + switch (type) + { + case GRUB_BIDI_TYPE_RLE: + push_stack (cur_override, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_RLO: + push_stack (OVERRIDE_R, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_LRE: + push_stack (cur_override, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_LRO: + push_stack (OVERRIDE_L, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_PDF: + pop_stack (); + break; + case GRUB_BIDI_TYPE_BN: + break; + default: + levels[no_markers_len] = cur_level; + if (cur_override != OVERRIDE_NEUTRAL) + resolved_types[no_markers_len] = + (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L : GRUB_BIDI_TYPE_R; + else + resolved_types[no_markers_len] = type; + no_markers[no_markers_len] = logical[i]; + no_markers_len++; + } + } + + for (run_start = 0; run_start < no_markers_len; run_start = run_end) + { + unsigned prev_level, next_level, cur_run_level; + unsigned last_type, last_strong_type; + for (run_end = run_start; run_end < no_markers_len && + levels[run_end] == levels[run_start]; run_end++); + if (run_start == 0) + prev_level = base_level; + else + prev_level = levels[run_start - 1]; + if (run_end == no_markers_len) + next_level = base_level; + else + next_level = levels[run_end]; + cur_run_level = levels[run_start]; + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + last_strong_type = last_type; + for (i = run_start; i < run_end; i++) + { + switch (resolved_types[i]) + { + case GRUB_BIDI_TYPE_NSM: + resolved_types[i] = last_type; + break; + case GRUB_BIDI_TYPE_EN: + if (last_strong_type == GRUB_BIDI_TYPE_AL) + resolved_types[i] = GRUB_BIDI_TYPE_AN; + break; + case GRUB_BIDI_TYPE_L: + case GRUB_BIDI_TYPE_R: + last_strong_type = resolved_types[i]; + break; + case GRUB_BIDI_TYPE_ES: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) + resolved_types[i] = GRUB_BIDI_TYPE_EN; + else + resolved_types[i] = GRUB_BIDI_TYPE_ON; + break; + case GRUB_BIDI_TYPE_ET: + { + unsigned j; + if (last_type == GRUB_BIDI_TYPE_EN) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + for (j = i; j < run_end + && resolved_types[j] == GRUB_BIDI_TYPE_ET; j++); + if (j != run_end && resolved_types[j] == GRUB_BIDI_TYPE_EN) + { + for (; i < run_end + && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) + resolved_types[i] = GRUB_BIDI_TYPE_EN; + i--; + break; + } + for (; i < run_end + && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) + resolved_types[i] = GRUB_BIDI_TYPE_ON; + i--; + break; + } + break; + case GRUB_BIDI_TYPE_CS: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + if (last_type == GRUB_BIDI_TYPE_AN + && i + 1 < run_end + && (resolved_types[i + 1] == GRUB_BIDI_TYPE_AN + || (resolved_types[i + 1] == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_AL))) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + resolved_types[i] = GRUB_BIDI_TYPE_ON; + break; + case GRUB_BIDI_TYPE_AL: + last_strong_type = resolved_types[i]; + resolved_types[i] = GRUB_BIDI_TYPE_R; + break; + default: /* Make GCC happy. */ + break; + } + last_type = resolved_types[i]; + if (resolved_types[i] == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_L) + resolved_types[i] = GRUB_BIDI_TYPE_L; + } + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + for (i = run_start; i < run_end; ) + { + unsigned j; + unsigned next_type; + for (j = i; j < run_end && + (resolved_types[j] == GRUB_BIDI_TYPE_B + || resolved_types[j] == GRUB_BIDI_TYPE_S + || resolved_types[j] == GRUB_BIDI_TYPE_WS + || resolved_types[j] == GRUB_BIDI_TYPE_ON); j++); + if (j == i) + { + if (resolved_types[i] == GRUB_BIDI_TYPE_L) + last_type = GRUB_BIDI_TYPE_L; + else + last_type = GRUB_BIDI_TYPE_R; + i++; + continue; + } + if (j == run_end) + next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; + else + { + if (resolved_types[j] == GRUB_BIDI_TYPE_L) + next_type = GRUB_BIDI_TYPE_L; + else + next_type = GRUB_BIDI_TYPE_R; + } + if (next_type == last_type) + for (; i < j; i++) + resolved_types[i] = last_type; + else + for (; i < j; i++) + resolved_types[i] = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R + : GRUB_BIDI_TYPE_L; + } + } + + for (i = 0; i < no_markers_len; i++) + { + if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R) + { + levels[i]++; + continue; + } + if (!(levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_AN + || resolved_types[i] == GRUB_BIDI_TYPE_EN)) + { + levels[i] += 2; + continue; + } + if ((levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_L + || resolved_types[i] == GRUB_BIDI_TYPE_AN + || resolved_types[i] == GRUB_BIDI_TYPE_EN)) + { + levels[i]++; + continue; + } + } + grub_free (resolved_types); + /* TODO: put line-wrapping here. */ + { + unsigned min_odd_level = 0xffffffff; + unsigned max_level = 0; + unsigned j; + for (i = 0; i < no_markers_len; i++) + { + if (levels[i] > max_level) + max_level = levels[i]; + if (levels[i] < min_odd_level && (levels[i] & 1)) + min_odd_level = levels[i]; + } + for (j = max_level; j >= min_odd_level; j--) + { + unsigned in = 0; + for (i = 0; i < no_markers_len; i++) + { + if (i != 0 && levels[i] >= j && levels[i-1] < j) + in = i; + if (levels[i] >= j && (i + 1 == no_markers_len || levels[i+1] < j)) + revert (in, i); + } + } + } + + grub_free (levels); + + *visual = no_markers; + return no_markers_len; +} + /* 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. @@ -1057,19 +1412,29 @@ grub_font_draw_string (const char *str, grub_font_t font, { int x; struct grub_font_glyph *glyph; - grub_uint32_t code; - const grub_uint8_t *ptr; + grub_uint32_t *logical, *visual, *ptr; + grub_ssize_t logical_len, visual_len; - for (ptr = (const grub_uint8_t *) str, x = left_x; - grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; ) + logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); + if (logical_len < 0) + return grub_errno; + + visual_len = grub_err_bidi_logical_to_visual (logical, logical_len, &visual); + grub_free (logical); + if (visual_len < 0) + return grub_errno; + + for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++) { - glyph = grub_font_get_glyph_with_fallback (font, code); + glyph = grub_font_get_glyph_with_fallback (font, *ptr); if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE) return grub_errno; x += glyph->device_width; } + grub_free (visual); + return GRUB_ERR_NONE; } diff --git a/include/grub/bidi.h b/include/grub/bidi.h new file mode 100644 index 000000000..8612d6e24 --- /dev/null +++ b/include/grub/bidi.h @@ -0,0 +1,60 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_BIDI_HEADER +#define GRUB_BIDI_HEADER 1 + +#include + +struct grub_bidi_compact_range +{ + grub_uint32_t start:24; + grub_uint32_t end:24; + grub_uint8_t type; +} __attribute__ ((packed)); + +enum grub_bidi_type + { + GRUB_BIDI_TYPE_L = 0, + GRUB_BIDI_TYPE_LRE, + GRUB_BIDI_TYPE_LRO, + GRUB_BIDI_TYPE_R, + GRUB_BIDI_TYPE_AL, + GRUB_BIDI_TYPE_RLE, + GRUB_BIDI_TYPE_RLO, + GRUB_BIDI_TYPE_PDF, + GRUB_BIDI_TYPE_EN, + GRUB_BIDI_TYPE_ES, + GRUB_BIDI_TYPE_ET, + GRUB_BIDI_TYPE_AN, + GRUB_BIDI_TYPE_CS, + GRUB_BIDI_TYPE_NSM, + GRUB_BIDI_TYPE_BN, + GRUB_BIDI_TYPE_B, + GRUB_BIDI_TYPE_S, + GRUB_BIDI_TYPE_WS, + GRUB_BIDI_TYPE_ON + }; + +extern struct grub_bidi_compact_range grub_bidi_compact[]; + +#define GRUB_BIDI_MAX_CACHED_UNICODE_CHAR 0x20000 +/* Unicode mandates an arbitrary limit. */ +#define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61 + +#endif diff --git a/unidata.c b/unidata.c new file mode 100644 index 000000000..f4467c920 --- /dev/null +++ b/unidata.c @@ -0,0 +1,458 @@ +#include + +struct grub_bidi_compact_range grub_bidi_compact[] = { +{0x0, 0x8, GRUB_BIDI_TYPE_BN}, +{0x9, 0x9, GRUB_BIDI_TYPE_S}, +{0xa, 0xa, GRUB_BIDI_TYPE_B}, +{0xb, 0xb, GRUB_BIDI_TYPE_S}, +{0xc, 0xc, GRUB_BIDI_TYPE_WS}, +{0xd, 0xd, GRUB_BIDI_TYPE_B}, +{0xe, 0x1b, GRUB_BIDI_TYPE_BN}, +{0x1c, 0x1e, GRUB_BIDI_TYPE_B}, +{0x1f, 0x1f, GRUB_BIDI_TYPE_S}, +{0x20, 0x20, GRUB_BIDI_TYPE_WS}, +{0x21, 0x22, GRUB_BIDI_TYPE_ON}, +{0x23, 0x25, GRUB_BIDI_TYPE_ET}, +{0x26, 0x2a, GRUB_BIDI_TYPE_ON}, +{0x2b, 0x2b, GRUB_BIDI_TYPE_ES}, +{0x2c, 0x2c, GRUB_BIDI_TYPE_CS}, +{0x2d, 0x2d, GRUB_BIDI_TYPE_ES}, +{0x2e, 0x2f, GRUB_BIDI_TYPE_CS}, +{0x30, 0x39, GRUB_BIDI_TYPE_EN}, +{0x3a, 0x3a, GRUB_BIDI_TYPE_CS}, +{0x3b, 0x40, GRUB_BIDI_TYPE_ON}, +{0x5b, 0x60, GRUB_BIDI_TYPE_ON}, +{0x7b, 0x7e, GRUB_BIDI_TYPE_ON}, +{0x7f, 0x84, GRUB_BIDI_TYPE_BN}, +{0x85, 0x85, GRUB_BIDI_TYPE_B}, +{0x86, 0x9f, GRUB_BIDI_TYPE_BN}, +{0xa0, 0xa0, GRUB_BIDI_TYPE_CS}, +{0xa1, 0xa1, GRUB_BIDI_TYPE_ON}, +{0xa2, 0xa5, GRUB_BIDI_TYPE_ET}, +{0xa6, 0xa9, GRUB_BIDI_TYPE_ON}, +{0xab, 0xac, GRUB_BIDI_TYPE_ON}, +{0xad, 0xad, GRUB_BIDI_TYPE_BN}, +{0xae, 0xaf, GRUB_BIDI_TYPE_ON}, +{0xb0, 0xb1, GRUB_BIDI_TYPE_ET}, +{0xb2, 0xb3, GRUB_BIDI_TYPE_EN}, +{0xb4, 0xb4, GRUB_BIDI_TYPE_ON}, +{0xb6, 0xb8, GRUB_BIDI_TYPE_ON}, +{0xb9, 0xb9, GRUB_BIDI_TYPE_EN}, +{0xbb, 0xbf, GRUB_BIDI_TYPE_ON}, +{0xd7, 0xd7, GRUB_BIDI_TYPE_ON}, +{0xf7, 0xf7, GRUB_BIDI_TYPE_ON}, +{0x2b9, 0x2ba, GRUB_BIDI_TYPE_ON}, +{0x2c2, 0x2cf, GRUB_BIDI_TYPE_ON}, +{0x2d2, 0x2df, GRUB_BIDI_TYPE_ON}, +{0x2e5, 0x2ed, GRUB_BIDI_TYPE_ON}, +{0x2ef, 0x2ff, GRUB_BIDI_TYPE_ON}, +{0x300, 0x36f, GRUB_BIDI_TYPE_NSM}, +{0x374, 0x375, GRUB_BIDI_TYPE_ON}, +{0x37e, 0x37e, GRUB_BIDI_TYPE_ON}, +{0x384, 0x385, GRUB_BIDI_TYPE_ON}, +{0x387, 0x387, GRUB_BIDI_TYPE_ON}, +{0x3f6, 0x3f6, GRUB_BIDI_TYPE_ON}, +{0x483, 0x489, GRUB_BIDI_TYPE_NSM}, +{0x58a, 0x58a, GRUB_BIDI_TYPE_ON}, +{0x591, 0x5bd, GRUB_BIDI_TYPE_NSM}, +{0x5be, 0x5be, GRUB_BIDI_TYPE_R}, +{0x5bf, 0x5bf, GRUB_BIDI_TYPE_NSM}, +{0x5c0, 0x5c0, GRUB_BIDI_TYPE_R}, +{0x5c1, 0x5c2, GRUB_BIDI_TYPE_NSM}, +{0x5c3, 0x5c3, GRUB_BIDI_TYPE_R}, +{0x5c4, 0x5c5, GRUB_BIDI_TYPE_NSM}, +{0x5c6, 0x5c6, GRUB_BIDI_TYPE_R}, +{0x5c7, 0x5c7, GRUB_BIDI_TYPE_NSM}, +{0x5d0, 0x5ea, GRUB_BIDI_TYPE_R}, +{0x5f0, 0x5f4, GRUB_BIDI_TYPE_R}, +{0x600, 0x603, GRUB_BIDI_TYPE_AN}, +{0x606, 0x607, GRUB_BIDI_TYPE_ON}, +{0x608, 0x608, GRUB_BIDI_TYPE_AL}, +{0x609, 0x60a, GRUB_BIDI_TYPE_ET}, +{0x60b, 0x60b, GRUB_BIDI_TYPE_AL}, +{0x60c, 0x60c, GRUB_BIDI_TYPE_CS}, +{0x60d, 0x60d, GRUB_BIDI_TYPE_AL}, +{0x60e, 0x60f, GRUB_BIDI_TYPE_ON}, +{0x610, 0x61a, GRUB_BIDI_TYPE_NSM}, +{0x61b, 0x61b, GRUB_BIDI_TYPE_AL}, +{0x61e, 0x61f, GRUB_BIDI_TYPE_AL}, +{0x621, 0x64a, GRUB_BIDI_TYPE_AL}, +{0x64b, 0x65e, GRUB_BIDI_TYPE_NSM}, +{0x660, 0x669, GRUB_BIDI_TYPE_AN}, +{0x66a, 0x66a, GRUB_BIDI_TYPE_ET}, +{0x66b, 0x66c, GRUB_BIDI_TYPE_AN}, +{0x66d, 0x66f, GRUB_BIDI_TYPE_AL}, +{0x670, 0x670, GRUB_BIDI_TYPE_NSM}, +{0x671, 0x6d5, GRUB_BIDI_TYPE_AL}, +{0x6d6, 0x6dc, GRUB_BIDI_TYPE_NSM}, +{0x6dd, 0x6dd, GRUB_BIDI_TYPE_AN}, +{0x6de, 0x6e4, GRUB_BIDI_TYPE_NSM}, +{0x6e5, 0x6e6, GRUB_BIDI_TYPE_AL}, +{0x6e7, 0x6e8, GRUB_BIDI_TYPE_NSM}, +{0x6e9, 0x6e9, GRUB_BIDI_TYPE_ON}, +{0x6ea, 0x6ed, GRUB_BIDI_TYPE_NSM}, +{0x6ee, 0x6ef, GRUB_BIDI_TYPE_AL}, +{0x6f0, 0x6f9, GRUB_BIDI_TYPE_EN}, +{0x6fa, 0x70d, GRUB_BIDI_TYPE_AL}, +{0x70f, 0x70f, GRUB_BIDI_TYPE_BN}, +{0x710, 0x710, GRUB_BIDI_TYPE_AL}, +{0x711, 0x711, GRUB_BIDI_TYPE_NSM}, +{0x712, 0x72f, GRUB_BIDI_TYPE_AL}, +{0x730, 0x74a, GRUB_BIDI_TYPE_NSM}, +{0x74d, 0x7a5, GRUB_BIDI_TYPE_AL}, +{0x7a6, 0x7b0, GRUB_BIDI_TYPE_NSM}, +{0x7b1, 0x7b1, GRUB_BIDI_TYPE_AL}, +{0x7c0, 0x7ea, GRUB_BIDI_TYPE_R}, +{0x7eb, 0x7f3, GRUB_BIDI_TYPE_NSM}, +{0x7f4, 0x7f5, GRUB_BIDI_TYPE_R}, +{0x7f6, 0x7f9, GRUB_BIDI_TYPE_ON}, +{0x7fa, 0x7fa, GRUB_BIDI_TYPE_R}, +{0x901, 0x902, GRUB_BIDI_TYPE_NSM}, +{0x93c, 0x93c, GRUB_BIDI_TYPE_NSM}, +{0x941, 0x948, GRUB_BIDI_TYPE_NSM}, +{0x94d, 0x94d, GRUB_BIDI_TYPE_NSM}, +{0x951, 0x954, GRUB_BIDI_TYPE_NSM}, +{0x962, 0x963, GRUB_BIDI_TYPE_NSM}, +{0x981, 0x981, GRUB_BIDI_TYPE_NSM}, +{0x9bc, 0x9bc, GRUB_BIDI_TYPE_NSM}, +{0x9c1, 0x9c4, GRUB_BIDI_TYPE_NSM}, +{0x9cd, 0x9cd, GRUB_BIDI_TYPE_NSM}, +{0x9e2, 0x9e3, GRUB_BIDI_TYPE_NSM}, +{0x9f2, 0x9f3, GRUB_BIDI_TYPE_ET}, +{0xa01, 0xa02, GRUB_BIDI_TYPE_NSM}, +{0xa3c, 0xa3c, GRUB_BIDI_TYPE_NSM}, +{0xa41, 0xa42, GRUB_BIDI_TYPE_NSM}, +{0xa47, 0xa48, GRUB_BIDI_TYPE_NSM}, +{0xa4b, 0xa4d, GRUB_BIDI_TYPE_NSM}, +{0xa51, 0xa51, GRUB_BIDI_TYPE_NSM}, +{0xa70, 0xa71, GRUB_BIDI_TYPE_NSM}, +{0xa75, 0xa75, GRUB_BIDI_TYPE_NSM}, +{0xa81, 0xa82, GRUB_BIDI_TYPE_NSM}, +{0xabc, 0xabc, GRUB_BIDI_TYPE_NSM}, +{0xac1, 0xac5, GRUB_BIDI_TYPE_NSM}, +{0xac7, 0xac8, GRUB_BIDI_TYPE_NSM}, +{0xacd, 0xacd, GRUB_BIDI_TYPE_NSM}, +{0xae2, 0xae3, GRUB_BIDI_TYPE_NSM}, +{0xaf1, 0xaf1, GRUB_BIDI_TYPE_ET}, +{0xb01, 0xb01, GRUB_BIDI_TYPE_NSM}, +{0xb3c, 0xb3c, GRUB_BIDI_TYPE_NSM}, +{0xb3f, 0xb3f, GRUB_BIDI_TYPE_NSM}, +{0xb41, 0xb44, GRUB_BIDI_TYPE_NSM}, +{0xb4d, 0xb4d, GRUB_BIDI_TYPE_NSM}, +{0xb56, 0xb56, GRUB_BIDI_TYPE_NSM}, +{0xb62, 0xb63, GRUB_BIDI_TYPE_NSM}, +{0xb82, 0xb82, GRUB_BIDI_TYPE_NSM}, +{0xbc0, 0xbc0, GRUB_BIDI_TYPE_NSM}, +{0xbcd, 0xbcd, GRUB_BIDI_TYPE_NSM}, +{0xbf3, 0xbf8, GRUB_BIDI_TYPE_ON}, +{0xbf9, 0xbf9, GRUB_BIDI_TYPE_ET}, +{0xbfa, 0xbfa, GRUB_BIDI_TYPE_ON}, +{0xc3e, 0xc40, GRUB_BIDI_TYPE_NSM}, +{0xc46, 0xc48, GRUB_BIDI_TYPE_NSM}, +{0xc4a, 0xc4d, GRUB_BIDI_TYPE_NSM}, +{0xc55, 0xc56, GRUB_BIDI_TYPE_NSM}, +{0xc62, 0xc63, GRUB_BIDI_TYPE_NSM}, +{0xc78, 0xc7e, GRUB_BIDI_TYPE_ON}, +{0xcbc, 0xcbc, GRUB_BIDI_TYPE_NSM}, +{0xccc, 0xccd, GRUB_BIDI_TYPE_NSM}, +{0xce2, 0xce3, GRUB_BIDI_TYPE_NSM}, +{0xcf1, 0xcf2, GRUB_BIDI_TYPE_ON}, +{0xd41, 0xd44, GRUB_BIDI_TYPE_NSM}, +{0xd4d, 0xd4d, GRUB_BIDI_TYPE_NSM}, +{0xd62, 0xd63, GRUB_BIDI_TYPE_NSM}, +{0xdca, 0xdca, GRUB_BIDI_TYPE_NSM}, +{0xdd2, 0xdd4, GRUB_BIDI_TYPE_NSM}, +{0xdd6, 0xdd6, GRUB_BIDI_TYPE_NSM}, +{0xe31, 0xe31, GRUB_BIDI_TYPE_NSM}, +{0xe34, 0xe3a, GRUB_BIDI_TYPE_NSM}, +{0xe3f, 0xe3f, GRUB_BIDI_TYPE_ET}, +{0xe47, 0xe4e, GRUB_BIDI_TYPE_NSM}, +{0xeb1, 0xeb1, GRUB_BIDI_TYPE_NSM}, +{0xeb4, 0xeb9, GRUB_BIDI_TYPE_NSM}, +{0xebb, 0xebc, GRUB_BIDI_TYPE_NSM}, +{0xec8, 0xecd, GRUB_BIDI_TYPE_NSM}, +{0xf18, 0xf19, GRUB_BIDI_TYPE_NSM}, +{0xf35, 0xf35, GRUB_BIDI_TYPE_NSM}, +{0xf37, 0xf37, GRUB_BIDI_TYPE_NSM}, +{0xf39, 0xf39, GRUB_BIDI_TYPE_NSM}, +{0xf3a, 0xf3d, GRUB_BIDI_TYPE_ON}, +{0xf71, 0xf7e, GRUB_BIDI_TYPE_NSM}, +{0xf80, 0xf84, GRUB_BIDI_TYPE_NSM}, +{0xf86, 0xf87, GRUB_BIDI_TYPE_NSM}, +{0xf90, 0xf97, GRUB_BIDI_TYPE_NSM}, +{0xf99, 0xfbc, GRUB_BIDI_TYPE_NSM}, +{0xfc6, 0xfc6, GRUB_BIDI_TYPE_NSM}, +{0x102d, 0x1030, GRUB_BIDI_TYPE_NSM}, +{0x1032, 0x1037, GRUB_BIDI_TYPE_NSM}, +{0x1039, 0x103a, GRUB_BIDI_TYPE_NSM}, +{0x103d, 0x103e, GRUB_BIDI_TYPE_NSM}, +{0x1058, 0x1059, GRUB_BIDI_TYPE_NSM}, +{0x105e, 0x1060, GRUB_BIDI_TYPE_NSM}, +{0x1071, 0x1074, GRUB_BIDI_TYPE_NSM}, +{0x1082, 0x1082, GRUB_BIDI_TYPE_NSM}, +{0x1085, 0x1086, GRUB_BIDI_TYPE_NSM}, +{0x108d, 0x108d, GRUB_BIDI_TYPE_NSM}, +{0x135f, 0x135f, GRUB_BIDI_TYPE_NSM}, +{0x1390, 0x1399, GRUB_BIDI_TYPE_ON}, +{0x1680, 0x1680, GRUB_BIDI_TYPE_WS}, +{0x169b, 0x169c, GRUB_BIDI_TYPE_ON}, +{0x1712, 0x1714, GRUB_BIDI_TYPE_NSM}, +{0x1732, 0x1734, GRUB_BIDI_TYPE_NSM}, +{0x1752, 0x1753, GRUB_BIDI_TYPE_NSM}, +{0x1772, 0x1773, GRUB_BIDI_TYPE_NSM}, +{0x17b7, 0x17bd, GRUB_BIDI_TYPE_NSM}, +{0x17c6, 0x17c6, GRUB_BIDI_TYPE_NSM}, +{0x17c9, 0x17d3, GRUB_BIDI_TYPE_NSM}, +{0x17db, 0x17db, GRUB_BIDI_TYPE_ET}, +{0x17dd, 0x17dd, GRUB_BIDI_TYPE_NSM}, +{0x17f0, 0x17f9, GRUB_BIDI_TYPE_ON}, +{0x1800, 0x180a, GRUB_BIDI_TYPE_ON}, +{0x180b, 0x180d, GRUB_BIDI_TYPE_NSM}, +{0x180e, 0x180e, GRUB_BIDI_TYPE_WS}, +{0x18a9, 0x18a9, GRUB_BIDI_TYPE_NSM}, +{0x1920, 0x1922, GRUB_BIDI_TYPE_NSM}, +{0x1927, 0x1928, GRUB_BIDI_TYPE_NSM}, +{0x1932, 0x1932, GRUB_BIDI_TYPE_NSM}, +{0x1939, 0x193b, GRUB_BIDI_TYPE_NSM}, +{0x1940, 0x1940, GRUB_BIDI_TYPE_ON}, +{0x1944, 0x1945, GRUB_BIDI_TYPE_ON}, +{0x19de, 0x19ff, GRUB_BIDI_TYPE_ON}, +{0x1a17, 0x1a18, GRUB_BIDI_TYPE_NSM}, +{0x1b00, 0x1b03, GRUB_BIDI_TYPE_NSM}, +{0x1b34, 0x1b34, GRUB_BIDI_TYPE_NSM}, +{0x1b36, 0x1b3a, GRUB_BIDI_TYPE_NSM}, +{0x1b3c, 0x1b3c, GRUB_BIDI_TYPE_NSM}, +{0x1b42, 0x1b42, GRUB_BIDI_TYPE_NSM}, +{0x1b6b, 0x1b73, GRUB_BIDI_TYPE_NSM}, +{0x1b80, 0x1b81, GRUB_BIDI_TYPE_NSM}, +{0x1ba2, 0x1ba5, GRUB_BIDI_TYPE_NSM}, +{0x1ba8, 0x1ba9, GRUB_BIDI_TYPE_NSM}, +{0x1c2c, 0x1c33, GRUB_BIDI_TYPE_NSM}, +{0x1c36, 0x1c37, GRUB_BIDI_TYPE_NSM}, +{0x1dc0, 0x1de6, GRUB_BIDI_TYPE_NSM}, +{0x1dfe, 0x1dff, GRUB_BIDI_TYPE_NSM}, +{0x1fbd, 0x1fbd, GRUB_BIDI_TYPE_ON}, +{0x1fbf, 0x1fc1, GRUB_BIDI_TYPE_ON}, +{0x1fcd, 0x1fcf, GRUB_BIDI_TYPE_ON}, +{0x1fdd, 0x1fdf, GRUB_BIDI_TYPE_ON}, +{0x1fed, 0x1fef, GRUB_BIDI_TYPE_ON}, +{0x1ffd, 0x1ffe, GRUB_BIDI_TYPE_ON}, +{0x2000, 0x200a, GRUB_BIDI_TYPE_WS}, +{0x200b, 0x200d, GRUB_BIDI_TYPE_BN}, +{0x200f, 0x200f, GRUB_BIDI_TYPE_R}, +{0x2010, 0x2027, GRUB_BIDI_TYPE_ON}, +{0x2028, 0x2028, GRUB_BIDI_TYPE_WS}, +{0x2029, 0x2029, GRUB_BIDI_TYPE_B}, +{0x202a, 0x202a, GRUB_BIDI_TYPE_LRE}, +{0x202b, 0x202b, GRUB_BIDI_TYPE_RLE}, +{0x202c, 0x202c, GRUB_BIDI_TYPE_PDF}, +{0x202d, 0x202d, GRUB_BIDI_TYPE_LRO}, +{0x202e, 0x202e, GRUB_BIDI_TYPE_RLO}, +{0x202f, 0x202f, GRUB_BIDI_TYPE_CS}, +{0x2030, 0x2034, GRUB_BIDI_TYPE_ET}, +{0x2035, 0x2043, GRUB_BIDI_TYPE_ON}, +{0x2044, 0x2044, GRUB_BIDI_TYPE_CS}, +{0x2045, 0x205e, GRUB_BIDI_TYPE_ON}, +{0x205f, 0x205f, GRUB_BIDI_TYPE_WS}, +{0x2060, 0x2064, GRUB_BIDI_TYPE_BN}, +{0x206a, 0x206f, GRUB_BIDI_TYPE_BN}, +{0x2070, 0x2070, GRUB_BIDI_TYPE_EN}, +{0x2074, 0x2079, GRUB_BIDI_TYPE_EN}, +{0x207a, 0x207b, GRUB_BIDI_TYPE_ES}, +{0x207c, 0x207e, GRUB_BIDI_TYPE_ON}, +{0x2080, 0x2089, GRUB_BIDI_TYPE_EN}, +{0x208a, 0x208b, GRUB_BIDI_TYPE_ES}, +{0x208c, 0x208e, GRUB_BIDI_TYPE_ON}, +{0x20a0, 0x20b5, GRUB_BIDI_TYPE_ET}, +{0x20d0, 0x20f0, GRUB_BIDI_TYPE_NSM}, +{0x2100, 0x2101, GRUB_BIDI_TYPE_ON}, +{0x2103, 0x2106, GRUB_BIDI_TYPE_ON}, +{0x2108, 0x2109, GRUB_BIDI_TYPE_ON}, +{0x2114, 0x2114, GRUB_BIDI_TYPE_ON}, +{0x2116, 0x2118, GRUB_BIDI_TYPE_ON}, +{0x211e, 0x2123, GRUB_BIDI_TYPE_ON}, +{0x2125, 0x2125, GRUB_BIDI_TYPE_ON}, +{0x2127, 0x2127, GRUB_BIDI_TYPE_ON}, +{0x2129, 0x2129, GRUB_BIDI_TYPE_ON}, +{0x212e, 0x212e, GRUB_BIDI_TYPE_ET}, +{0x213a, 0x213b, GRUB_BIDI_TYPE_ON}, +{0x2140, 0x2144, GRUB_BIDI_TYPE_ON}, +{0x214a, 0x214d, GRUB_BIDI_TYPE_ON}, +{0x2153, 0x215f, GRUB_BIDI_TYPE_ON}, +{0x2190, 0x2211, GRUB_BIDI_TYPE_ON}, +{0x2212, 0x2212, GRUB_BIDI_TYPE_ES}, +{0x2213, 0x2213, GRUB_BIDI_TYPE_ET}, +{0x2214, 0x2335, GRUB_BIDI_TYPE_ON}, +{0x237b, 0x2394, GRUB_BIDI_TYPE_ON}, +{0x2396, 0x23e7, GRUB_BIDI_TYPE_ON}, +{0x2400, 0x2426, GRUB_BIDI_TYPE_ON}, +{0x2440, 0x244a, GRUB_BIDI_TYPE_ON}, +{0x2460, 0x2487, GRUB_BIDI_TYPE_ON}, +{0x2488, 0x249b, GRUB_BIDI_TYPE_EN}, +{0x24ea, 0x269d, GRUB_BIDI_TYPE_ON}, +{0x26a0, 0x26ab, GRUB_BIDI_TYPE_ON}, +{0x26ad, 0x26bc, GRUB_BIDI_TYPE_ON}, +{0x26c0, 0x26c3, GRUB_BIDI_TYPE_ON}, +{0x2701, 0x2704, GRUB_BIDI_TYPE_ON}, +{0x2706, 0x2709, GRUB_BIDI_TYPE_ON}, +{0x270c, 0x2727, GRUB_BIDI_TYPE_ON}, +{0x2729, 0x274b, GRUB_BIDI_TYPE_ON}, +{0x274d, 0x274d, GRUB_BIDI_TYPE_ON}, +{0x274f, 0x2752, GRUB_BIDI_TYPE_ON}, +{0x2756, 0x2756, GRUB_BIDI_TYPE_ON}, +{0x2758, 0x275e, GRUB_BIDI_TYPE_ON}, +{0x2761, 0x2794, GRUB_BIDI_TYPE_ON}, +{0x2798, 0x27af, GRUB_BIDI_TYPE_ON}, +{0x27b1, 0x27be, GRUB_BIDI_TYPE_ON}, +{0x27c0, 0x27ca, GRUB_BIDI_TYPE_ON}, +{0x27cc, 0x27cc, GRUB_BIDI_TYPE_ON}, +{0x27d0, 0x27ff, GRUB_BIDI_TYPE_ON}, +{0x2900, 0x2b4c, GRUB_BIDI_TYPE_ON}, +{0x2b50, 0x2b54, GRUB_BIDI_TYPE_ON}, +{0x2ce5, 0x2cea, GRUB_BIDI_TYPE_ON}, +{0x2cf9, 0x2cff, GRUB_BIDI_TYPE_ON}, +{0x2de0, 0x2dff, GRUB_BIDI_TYPE_NSM}, +{0x2e00, 0x2e30, GRUB_BIDI_TYPE_ON}, +{0x2e80, 0x2e99, GRUB_BIDI_TYPE_ON}, +{0x2e9b, 0x2ef3, GRUB_BIDI_TYPE_ON}, +{0x2f00, 0x2fd5, GRUB_BIDI_TYPE_ON}, +{0x2ff0, 0x2ffb, GRUB_BIDI_TYPE_ON}, +{0x3000, 0x3000, GRUB_BIDI_TYPE_WS}, +{0x3001, 0x3004, GRUB_BIDI_TYPE_ON}, +{0x3008, 0x3020, GRUB_BIDI_TYPE_ON}, +{0x302a, 0x302f, GRUB_BIDI_TYPE_NSM}, +{0x3030, 0x3030, GRUB_BIDI_TYPE_ON}, +{0x3036, 0x3037, GRUB_BIDI_TYPE_ON}, +{0x303d, 0x303f, GRUB_BIDI_TYPE_ON}, +{0x3099, 0x309a, GRUB_BIDI_TYPE_NSM}, +{0x309b, 0x309c, GRUB_BIDI_TYPE_ON}, +{0x30a0, 0x30a0, GRUB_BIDI_TYPE_ON}, +{0x30fb, 0x30fb, GRUB_BIDI_TYPE_ON}, +{0x31c0, 0x31e3, GRUB_BIDI_TYPE_ON}, +{0x321d, 0x321e, GRUB_BIDI_TYPE_ON}, +{0x3250, 0x325f, GRUB_BIDI_TYPE_ON}, +{0x327c, 0x327e, GRUB_BIDI_TYPE_ON}, +{0x32b1, 0x32bf, GRUB_BIDI_TYPE_ON}, +{0x32cc, 0x32cf, GRUB_BIDI_TYPE_ON}, +{0x3377, 0x337a, GRUB_BIDI_TYPE_ON}, +{0x33de, 0x33df, GRUB_BIDI_TYPE_ON}, +{0x33ff, 0x33ff, GRUB_BIDI_TYPE_ON}, +{0x4dc0, 0x4dff, GRUB_BIDI_TYPE_ON}, +{0xa490, 0xa4c6, GRUB_BIDI_TYPE_ON}, +{0xa60d, 0xa60f, GRUB_BIDI_TYPE_ON}, +{0xa66f, 0xa672, GRUB_BIDI_TYPE_NSM}, +{0xa673, 0xa673, GRUB_BIDI_TYPE_ON}, +{0xa67c, 0xa67d, GRUB_BIDI_TYPE_NSM}, +{0xa67e, 0xa67f, GRUB_BIDI_TYPE_ON}, +{0xa700, 0xa721, GRUB_BIDI_TYPE_ON}, +{0xa788, 0xa788, GRUB_BIDI_TYPE_ON}, +{0xa802, 0xa802, GRUB_BIDI_TYPE_NSM}, +{0xa806, 0xa806, GRUB_BIDI_TYPE_NSM}, +{0xa80b, 0xa80b, GRUB_BIDI_TYPE_NSM}, +{0xa825, 0xa826, GRUB_BIDI_TYPE_NSM}, +{0xa828, 0xa82b, GRUB_BIDI_TYPE_ON}, +{0xa874, 0xa877, GRUB_BIDI_TYPE_ON}, +{0xa8c4, 0xa8c4, GRUB_BIDI_TYPE_NSM}, +{0xa926, 0xa92d, GRUB_BIDI_TYPE_NSM}, +{0xa947, 0xa951, GRUB_BIDI_TYPE_NSM}, +{0xaa29, 0xaa2e, GRUB_BIDI_TYPE_NSM}, +{0xaa31, 0xaa32, GRUB_BIDI_TYPE_NSM}, +{0xaa35, 0xaa36, GRUB_BIDI_TYPE_NSM}, +{0xaa43, 0xaa43, GRUB_BIDI_TYPE_NSM}, +{0xaa4c, 0xaa4c, GRUB_BIDI_TYPE_NSM}, +{0xfb1d, 0xfb1d, GRUB_BIDI_TYPE_R}, +{0xfb1e, 0xfb1e, GRUB_BIDI_TYPE_NSM}, +{0xfb1f, 0xfb28, GRUB_BIDI_TYPE_R}, +{0xfb29, 0xfb29, GRUB_BIDI_TYPE_ES}, +{0xfb2a, 0xfb36, GRUB_BIDI_TYPE_R}, +{0xfb38, 0xfb3c, GRUB_BIDI_TYPE_R}, +{0xfb3e, 0xfb3e, GRUB_BIDI_TYPE_R}, +{0xfb40, 0xfb41, GRUB_BIDI_TYPE_R}, +{0xfb43, 0xfb44, GRUB_BIDI_TYPE_R}, +{0xfb46, 0xfb4f, GRUB_BIDI_TYPE_R}, +{0xfb50, 0xfbb1, GRUB_BIDI_TYPE_AL}, +{0xfbd3, 0xfd3d, GRUB_BIDI_TYPE_AL}, +{0xfd3e, 0xfd3f, GRUB_BIDI_TYPE_ON}, +{0xfd50, 0xfd8f, GRUB_BIDI_TYPE_AL}, +{0xfd92, 0xfdc7, GRUB_BIDI_TYPE_AL}, +{0xfdf0, 0xfdfc, GRUB_BIDI_TYPE_AL}, +{0xfdfd, 0xfdfd, GRUB_BIDI_TYPE_ON}, +{0xfe00, 0xfe0f, GRUB_BIDI_TYPE_NSM}, +{0xfe10, 0xfe19, GRUB_BIDI_TYPE_ON}, +{0xfe20, 0xfe26, GRUB_BIDI_TYPE_NSM}, +{0xfe30, 0xfe4f, GRUB_BIDI_TYPE_ON}, +{0xfe50, 0xfe50, GRUB_BIDI_TYPE_CS}, +{0xfe51, 0xfe51, GRUB_BIDI_TYPE_ON}, +{0xfe52, 0xfe52, GRUB_BIDI_TYPE_CS}, +{0xfe54, 0xfe54, GRUB_BIDI_TYPE_ON}, +{0xfe55, 0xfe55, GRUB_BIDI_TYPE_CS}, +{0xfe56, 0xfe5e, GRUB_BIDI_TYPE_ON}, +{0xfe5f, 0xfe5f, GRUB_BIDI_TYPE_ET}, +{0xfe60, 0xfe61, GRUB_BIDI_TYPE_ON}, +{0xfe62, 0xfe63, GRUB_BIDI_TYPE_ES}, +{0xfe64, 0xfe66, GRUB_BIDI_TYPE_ON}, +{0xfe68, 0xfe68, GRUB_BIDI_TYPE_ON}, +{0xfe69, 0xfe6a, GRUB_BIDI_TYPE_ET}, +{0xfe6b, 0xfe6b, GRUB_BIDI_TYPE_ON}, +{0xfe70, 0xfe74, GRUB_BIDI_TYPE_AL}, +{0xfe76, 0xfefc, GRUB_BIDI_TYPE_AL}, +{0xfeff, 0xfeff, GRUB_BIDI_TYPE_BN}, +{0xff01, 0xff02, GRUB_BIDI_TYPE_ON}, +{0xff03, 0xff05, GRUB_BIDI_TYPE_ET}, +{0xff06, 0xff0a, GRUB_BIDI_TYPE_ON}, +{0xff0b, 0xff0b, GRUB_BIDI_TYPE_ES}, +{0xff0c, 0xff0c, GRUB_BIDI_TYPE_CS}, +{0xff0d, 0xff0d, GRUB_BIDI_TYPE_ES}, +{0xff0e, 0xff0f, GRUB_BIDI_TYPE_CS}, +{0xff10, 0xff19, GRUB_BIDI_TYPE_EN}, +{0xff1a, 0xff1a, GRUB_BIDI_TYPE_CS}, +{0xff1b, 0xff20, GRUB_BIDI_TYPE_ON}, +{0xff3b, 0xff40, GRUB_BIDI_TYPE_ON}, +{0xff5b, 0xff65, GRUB_BIDI_TYPE_ON}, +{0xffe0, 0xffe1, GRUB_BIDI_TYPE_ET}, +{0xffe2, 0xffe4, GRUB_BIDI_TYPE_ON}, +{0xffe5, 0xffe6, GRUB_BIDI_TYPE_ET}, +{0xffe8, 0xffee, GRUB_BIDI_TYPE_ON}, +{0xfff9, 0xfffd, GRUB_BIDI_TYPE_ON}, +{0x10101, 0x10101, GRUB_BIDI_TYPE_ON}, +{0x10140, 0x1018a, GRUB_BIDI_TYPE_ON}, +{0x10190, 0x1019b, GRUB_BIDI_TYPE_ON}, +{0x101fd, 0x101fd, GRUB_BIDI_TYPE_NSM}, +{0x10800, 0x10805, GRUB_BIDI_TYPE_R}, +{0x10808, 0x10808, GRUB_BIDI_TYPE_R}, +{0x1080a, 0x10835, GRUB_BIDI_TYPE_R}, +{0x10837, 0x10838, GRUB_BIDI_TYPE_R}, +{0x1083c, 0x1083c, GRUB_BIDI_TYPE_R}, +{0x1083f, 0x1083f, GRUB_BIDI_TYPE_R}, +{0x10900, 0x10919, GRUB_BIDI_TYPE_R}, +{0x1091f, 0x1091f, GRUB_BIDI_TYPE_ON}, +{0x10920, 0x10939, GRUB_BIDI_TYPE_R}, +{0x1093f, 0x1093f, GRUB_BIDI_TYPE_R}, +{0x10a00, 0x10a00, GRUB_BIDI_TYPE_R}, +{0x10a01, 0x10a03, GRUB_BIDI_TYPE_NSM}, +{0x10a05, 0x10a06, GRUB_BIDI_TYPE_NSM}, +{0x10a0c, 0x10a0f, GRUB_BIDI_TYPE_NSM}, +{0x10a10, 0x10a13, GRUB_BIDI_TYPE_R}, +{0x10a15, 0x10a17, GRUB_BIDI_TYPE_R}, +{0x10a19, 0x10a33, GRUB_BIDI_TYPE_R}, +{0x10a38, 0x10a3a, GRUB_BIDI_TYPE_NSM}, +{0x10a3f, 0x10a3f, GRUB_BIDI_TYPE_NSM}, +{0x10a40, 0x10a47, GRUB_BIDI_TYPE_R}, +{0x10a50, 0x10a58, GRUB_BIDI_TYPE_R}, +{0x1d167, 0x1d169, GRUB_BIDI_TYPE_NSM}, +{0x1d173, 0x1d17a, GRUB_BIDI_TYPE_BN}, +{0x1d17b, 0x1d182, GRUB_BIDI_TYPE_NSM}, +{0x1d185, 0x1d18b, GRUB_BIDI_TYPE_NSM}, +{0x1d1aa, 0x1d1ad, GRUB_BIDI_TYPE_NSM}, +{0x1d200, 0x1d241, GRUB_BIDI_TYPE_ON}, +{0x1d242, 0x1d244, GRUB_BIDI_TYPE_NSM}, +{0x1d245, 0x1d245, GRUB_BIDI_TYPE_ON}, +{0x1d300, 0x1d356, GRUB_BIDI_TYPE_ON}, +{0x1d7ce, 0x1d7ff, GRUB_BIDI_TYPE_EN}, +{0x1f000, 0x1f02b, GRUB_BIDI_TYPE_ON}, +{0x1f030, 0x1f093, GRUB_BIDI_TYPE_ON}, +{0xe0001, 0xe0001, GRUB_BIDI_TYPE_BN}, +{0xe0020, 0xe007f, GRUB_BIDI_TYPE_BN}, +{0xe0100, 0xe01ef, GRUB_BIDI_TYPE_NSM}, +{0, 0, 0}, +}; \ No newline at end of file diff --git a/util/UnicodeData.txt b/util/UnicodeData.txt new file mode 100644 index 000000000..77db788cf --- /dev/null +++ b/util/UnicodeData.txt @@ -0,0 +1,19336 @@ +0000;;Cc;0;BN;;;;;N;NULL;;;; +0001;;Cc;0;BN;;;;;N;START OF HEADING;;;; +0002;;Cc;0;BN;;;;;N;START OF TEXT;;;; +0003;;Cc;0;BN;;;;;N;END OF TEXT;;;; +0004;;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;; +0005;;Cc;0;BN;;;;;N;ENQUIRY;;;; +0006;;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;; +0007;;Cc;0;BN;;;;;N;BELL;;;; +0008;;Cc;0;BN;;;;;N;BACKSPACE;;;; +0009;;Cc;0;S;;;;;N;CHARACTER TABULATION;;;; +000A;;Cc;0;B;;;;;N;LINE FEED (LF);;;; +000B;;Cc;0;S;;;;;N;LINE TABULATION;;;; +000C;;Cc;0;WS;;;;;N;FORM FEED (FF);;;; +000D;;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;; +000E;;Cc;0;BN;;;;;N;SHIFT OUT;;;; +000F;;Cc;0;BN;;;;;N;SHIFT IN;;;; +0010;;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;; +0011;;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;; +0012;;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;; +0013;;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;; +0014;;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;; +0015;;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;; +0016;;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;; +0017;;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;; +0018;;Cc;0;BN;;;;;N;CANCEL;;;; +0019;;Cc;0;BN;;;;;N;END OF MEDIUM;;;; +001A;;Cc;0;BN;;;;;N;SUBSTITUTE;;;; +001B;;Cc;0;BN;;;;;N;ESCAPE;;;; +001C;;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;; +001D;;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;; +001E;;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;; +001F;;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;; +0020;SPACE;Zs;0;WS;;;;;N;;;;; +0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;; +0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;; +0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;; +0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;; +0026;AMPERSAND;Po;0;ON;;;;;N;;;;; +0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;; +0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;; +0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;; +002A;ASTERISK;Po;0;ON;;;;;N;;;;; +002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;; +002C;COMMA;Po;0;CS;;;;;N;;;;; +002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;; +002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;; +002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;; +0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;; +0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;; +0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;; +0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;; +0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;; +0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;; +0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;; +0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;; +0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;; +0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;; +003A;COLON;Po;0;CS;;;;;N;;;;; +003B;SEMICOLON;Po;0;ON;;;;;N;;;;; +003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003F;QUESTION MARK;Po;0;ON;;;;;N;;;;; +0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;; +0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061; +0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062; +0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063; +0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064; +0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065; +0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066; +0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067; +0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068; +0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069; +004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A; +004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B; +004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C; +004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D; +004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E; +004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F; +0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070; +0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071; +0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072; +0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073; +0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074; +0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075; +0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076; +0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077; +0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078; +0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079; +005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A; +005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;; +005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;; +005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;; +005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;; +005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;; +0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;; +0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041 +0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042 +0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043 +0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044 +0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045 +0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046 +0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047 +0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048 +0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049 +006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A +006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B +006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C +006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D +006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E +006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F +0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050 +0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051 +0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052 +0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053 +0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054 +0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055 +0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056 +0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057 +0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058 +0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059 +007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A +007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;; +007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;; +007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;; +007E;TILDE;Sm;0;ON;;;;;N;;;;; +007F;;Cc;0;BN;;;;;N;DELETE;;;; +0080;;Cc;0;BN;;;;;N;;;;; +0081;;Cc;0;BN;;;;;N;;;;; +0082;;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;; +0083;;Cc;0;BN;;;;;N;NO BREAK HERE;;;; +0084;;Cc;0;BN;;;;;N;;;;; +0085;;Cc;0;B;;;;;N;NEXT LINE (NEL);;;; +0086;;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;; +0087;;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;; +0088;;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;; +0089;;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;; +008A;;Cc;0;BN;;;;;N;LINE TABULATION SET;;;; +008B;;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;; +008C;;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;; +008D;;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;; +008E;;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;; +008F;;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;; +0090;;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;; +0091;;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;; +0092;;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;; +0093;;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;; +0094;;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;; +0095;;Cc;0;BN;;;;;N;MESSAGE WAITING;;;; +0096;;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;; +0097;;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;; +0098;;Cc;0;BN;;;;;N;START OF STRING;;;; +0099;;Cc;0;BN;;;;;N;;;;; +009A;;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;; +009B;;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;; +009C;;Cc;0;BN;;;;;N;STRING TERMINATOR;;;; +009D;;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;; +009E;;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;; +009F;;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;; +00A0;NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;NON-BREAKING SPACE;;;; +00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;; +00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;; +00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;; +00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;; +00A7;SECTION SIGN;So;0;ON;;;;;N;;;;; +00A8;DIAERESIS;Sk;0;ON; 0020 0308;;;;N;SPACING DIAERESIS;;;; +00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;; +00AA;FEMININE ORDINAL INDICATOR;Ll;0;L; 0061;;;;N;;;;; +00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;*;;; +00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;; +00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;; +00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;; +00AF;MACRON;Sk;0;ON; 0020 0304;;;;N;SPACING MACRON;;;; +00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;; +00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;; +00B2;SUPERSCRIPT TWO;No;0;EN; 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;; +00B3;SUPERSCRIPT THREE;No;0;EN; 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;; +00B4;ACUTE ACCENT;Sk;0;ON; 0020 0301;;;;N;SPACING ACUTE;;;; +00B5;MICRO SIGN;Ll;0;L; 03BC;;;;N;;;039C;;039C +00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;; +00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;; +00B8;CEDILLA;Sk;0;ON; 0020 0327;;;;N;SPACING CEDILLA;;;; +00B9;SUPERSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;; +00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L; 006F;;;;N;;;;; +00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;*;;; +00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;; +00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;; +00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;; +00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;; +00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0; +00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1; +00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2; +00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3; +00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4; +00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5; +00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;ash *;;00E6; +00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7; +00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8; +00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9; +00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA; +00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB; +00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC; +00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED; +00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE; +00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF; +00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;Icelandic;;00F0; +00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1; +00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2; +00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3; +00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4; +00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5; +00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6; +00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;; +00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8; +00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9; +00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA; +00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB; +00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC; +00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD; +00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;Icelandic;;00FE; +00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;German;;; +00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0 +00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1 +00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2 +00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3 +00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4 +00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5 +00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;ash *;00C6;;00C6 +00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7 +00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8 +00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9 +00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA +00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB +00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC +00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD +00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE +00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF +00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;Icelandic;00D0;;00D0 +00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1 +00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2 +00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3 +00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4 +00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5 +00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6 +00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8 +00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9 +00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA +00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB +00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC +00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD +00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;Icelandic;00DE;;00DE +00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178 +0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101; +0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100 +0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103; +0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102 +0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105; +0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104 +0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107; +0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106 +0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109; +0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108 +010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B; +010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A +010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D; +010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C +010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F; +010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E +0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111; +0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110 +0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113; +0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112 +0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115; +0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114 +0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117; +0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116 +0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119; +0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118 +011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B; +011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A +011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D; +011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C +011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F; +011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E +0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121; +0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120 +0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123; +0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122 +0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125; +0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124 +0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127; +0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126 +0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129; +0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128 +012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B; +012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A +012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D; +012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C +012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F; +012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E +0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069; +0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049 +0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L; 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133; +0133;LATIN SMALL LIGATURE IJ;Ll;0;L; 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132 +0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135; +0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134 +0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137; +0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136 +0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;Greenlandic;;; +0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A; +013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139 +013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C; +013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B +013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E; +013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D +013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L; 004C 00B7;;;;N;;;;0140; +0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L; 006C 00B7;;;;N;;;013F;;013F +0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142; +0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141 +0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144; +0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143 +0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146; +0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145 +0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148; +0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147 +0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L; 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;; +014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;Sami;;014B; +014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;Sami;014A;;014A +014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D; +014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C +014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F; +014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E +0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151; +0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150 +0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153; +0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152 +0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155; +0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154 +0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157; +0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156 +0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159; +0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158 +015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B; +015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A +015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D; +015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C +015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;*;;015F; +015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;*;015E;;015E +0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161; +0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160 +0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;*;;0163; +0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;*;0162;;0162 +0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165; +0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164 +0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167; +0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166 +0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169; +0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168 +016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B; +016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A +016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D; +016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C +016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F; +016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E +0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171; +0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170 +0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173; +0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172 +0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175; +0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174 +0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177; +0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176 +0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF; +0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A; +017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179 +017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C; +017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B +017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E; +017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D +017F;LATIN SMALL LETTER LONG S;Ll;0;L; 0073;;;;N;;;0053;;0053 +0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;0243;;0243 +0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253; +0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183; +0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182 +0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185; +0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184 +0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254; +0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188; +0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187 +0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;*;;0256; +018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257; +018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C; +018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B +018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;; +018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD; +018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259; +0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B; +0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192; +0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191 +0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260; +0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263; +0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;hwair;01F6;;01F6 +0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269; +0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268; +0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199; +0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198 +019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D +019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;; +019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F; +019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272; +019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220 +019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;*;;0275; +01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1; +01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0 +01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;gha;;01A3; +01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;gha;01A2;;01A2 +01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5; +01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4 +01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;*;;0280; +01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8; +01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7 +01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283; +01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;; +01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;; +01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD; +01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC +01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288; +01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0; +01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF +01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A; +01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B; +01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4; +01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3 +01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6; +01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5 +01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292; +01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9; +01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8 +01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;; +01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;; +01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD; +01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC +01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;; +01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7 +01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;; +01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;; +01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;; +01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;; +01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L; 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5 +01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L; 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;01C5 +01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L; 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5 +01C7;LATIN CAPITAL LETTER LJ;Lu;0;L; 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8 +01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L; 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;01C8 +01C9;LATIN SMALL LETTER LJ;Ll;0;L; 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8 +01CA;LATIN CAPITAL LETTER NJ;Lu;0;L; 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB +01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L; 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;01CB +01CC;LATIN SMALL LETTER NJ;Ll;0;L; 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB +01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE; +01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD +01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0; +01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF +01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2; +01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1 +01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4; +01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3 +01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6; +01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5 +01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8; +01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7 +01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA; +01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9 +01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC; +01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB +01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E +01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF; +01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE +01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1; +01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0 +01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;ash *;;01E3; +01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;ash *;01E2;;01E2 +01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5; +01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4 +01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7; +01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6 +01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9; +01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8 +01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB; +01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA +01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED; +01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC +01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF; +01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE +01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;; +01F1;LATIN CAPITAL LETTER DZ;Lu;0;L; 0044 005A;;;;N;;;;01F3;01F2 +01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L; 0044 007A;;;;N;;;01F1;01F3;01F2 +01F3;LATIN SMALL LETTER DZ;Ll;0;L; 0064 007A;;;;N;;;01F1;;01F2 +01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5; +01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4 +01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195; +01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF; +01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9; +01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8 +01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB; +01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA +01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;ash *;;01FD; +01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;ash *;01FC;;01FC +01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF; +01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE +0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201; +0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200 +0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203; +0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202 +0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205; +0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204 +0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207; +0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206 +0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209; +0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208 +020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B; +020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A +020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D; +020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C +020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F; +020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E +0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211; +0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210 +0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213; +0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212 +0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215; +0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214 +0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217; +0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216 +0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;*;;0219; +0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;*;0218;;0218 +021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;*;;021B; +021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;*;021A;;021A +021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D; +021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C +021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F; +021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E +0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E; +0221;LATIN SMALL LETTER D WITH CURL;Ll;0;L;;;;;N;;;;; +0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223; +0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222 +0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225; +0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224 +0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227; +0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226 +0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229; +0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228 +022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B; +022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A +022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D; +022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C +022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F; +022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E +0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231; +0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230 +0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233; +0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232 +0234;LATIN SMALL LETTER L WITH CURL;Ll;0;L;;;;;N;;;;; +0235;LATIN SMALL LETTER N WITH CURL;Ll;0;L;;;;;N;;;;; +0236;LATIN SMALL LETTER T WITH CURL;Ll;0;L;;;;;N;;;;; +0237;LATIN SMALL LETTER DOTLESS J;Ll;0;L;;;;;N;;;;; +0238;LATIN SMALL LETTER DB DIGRAPH;Ll;0;L;;;;;N;;;;; +0239;LATIN SMALL LETTER QP DIGRAPH;Ll;0;L;;;;;N;;;;; +023A;LATIN CAPITAL LETTER A WITH STROKE;Lu;0;L;;;;;N;;;;2C65; +023B;LATIN CAPITAL LETTER C WITH STROKE;Lu;0;L;;;;;N;;;;023C; +023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B +023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A; +023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66; +023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;;; +0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;;; +0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242; +0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241 +0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180; +0244;LATIN CAPITAL LETTER U BAR;Lu;0;L;;;;;N;;;;0289; +0245;LATIN CAPITAL LETTER TURNED V;Lu;0;L;;;;;N;;;;028C; +0246;LATIN CAPITAL LETTER E WITH STROKE;Lu;0;L;;;;;N;;;;0247; +0247;LATIN SMALL LETTER E WITH STROKE;Ll;0;L;;;;;N;;;0246;;0246 +0248;LATIN CAPITAL LETTER J WITH STROKE;Lu;0;L;;;;;N;;;;0249; +0249;LATIN SMALL LETTER J WITH STROKE;Ll;0;L;;;;;N;;;0248;;0248 +024A;LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL;Lu;0;L;;;;;N;;;;024B; +024B;LATIN SMALL LETTER Q WITH HOOK TAIL;Ll;0;L;;;;;N;;;024A;;024A +024C;LATIN CAPITAL LETTER R WITH STROKE;Lu;0;L;;;;;N;;;;024D; +024D;LATIN SMALL LETTER R WITH STROKE;Ll;0;L;;;;;N;;;024C;;024C +024E;LATIN CAPITAL LETTER Y WITH STROKE;Lu;0;L;;;;;N;;;;024F; +024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E +0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F +0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D +0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;;; +0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181 +0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186 +0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;; +0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189 +0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A +0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;; +0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F +025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;; +025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190 +025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;; +025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;; +025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;; +025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;; +0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193 +0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;; +0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;; +0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194 +0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;; +0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;;; +0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;; +0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;; +0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197 +0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196 +026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;; +026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62 +026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;; +026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;; +026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;; +026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C +0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;; +0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;2C6E;;2C6E +0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D +0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;; +0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;; +0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F +0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;; +0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;; +0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;; +0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;; +027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;; +027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64 +027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;; +027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; +0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;*;01A6;;01A6 +0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; +0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;; +0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 +0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;; +0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;; +0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;; +0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;; +0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE +0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244 +028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1 +028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2 +028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;0245;;0245 +028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;; +028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;; +028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;; +0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;; +0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;; +0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7 +0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;; +0294;LATIN LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;; +0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;; +0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;; +0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;; +0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;; +029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;; +029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;; +029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;; +029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;; +029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;; +029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;; +02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;; +02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;; +02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;; +02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;; +02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;; +02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;; +02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;; +02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;; +02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;; +02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;; +02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;; +02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;; +02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02AE;LATIN SMALL LETTER TURNED H WITH FISHHOOK;Ll;0;L;;;;;N;;;;; +02AF;LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL;Ll;0;L;;;;;N;;;;; +02B0;MODIFIER LETTER SMALL H;Lm;0;L; 0068;;;;N;;;;; +02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L; 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;; +02B2;MODIFIER LETTER SMALL J;Lm;0;L; 006A;;;;N;;;;; +02B3;MODIFIER LETTER SMALL R;Lm;0;L; 0072;;;;N;;;;; +02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L; 0279;;;;N;;;;; +02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L; 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;; +02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L; 0281;;;;N;;;;; +02B7;MODIFIER LETTER SMALL W;Lm;0;L; 0077;;;;N;;;;; +02B8;MODIFIER LETTER SMALL Y;Lm;0;L; 0079;;;;N;;;;; +02B9;MODIFIER LETTER PRIME;Lm;0;ON;;;;;N;;;;; +02BA;MODIFIER LETTER DOUBLE PRIME;Lm;0;ON;;;;;N;;;;; +02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;; +02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;; +02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;; +02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;; +02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;; +02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;Mandarin Chinese third tone;;; +02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;; +02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;Mandarin Chinese first tone;;; +02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;Mandarin Chinese second tone;;; +02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;Mandarin Chinese fourth tone;;; +02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;; +02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;; +02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;; +02CF;MODIFIER LETTER LOW ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;; +02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;; +02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;; +02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;; +02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;; +02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;; +02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;; +02D8;BREVE;Sk;0;ON; 0020 0306;;;;N;SPACING BREVE;;;; +02D9;DOT ABOVE;Sk;0;ON; 0020 0307;;;;N;SPACING DOT ABOVE;Mandarin Chinese light tone;;; +02DA;RING ABOVE;Sk;0;ON; 0020 030A;;;;N;SPACING RING ABOVE;;;; +02DB;OGONEK;Sk;0;ON; 0020 0328;;;;N;SPACING OGONEK;;;; +02DC;SMALL TILDE;Sk;0;ON; 0020 0303;;;;N;SPACING TILDE;;;; +02DD;DOUBLE ACUTE ACCENT;Sk;0;ON; 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;; +02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;; +02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;; +02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L; 0263;;;;N;;;;; +02E1;MODIFIER LETTER SMALL L;Lm;0;L; 006C;;;;N;;;;; +02E2;MODIFIER LETTER SMALL S;Lm;0;L; 0073;;;;N;;;;; +02E3;MODIFIER LETTER SMALL X;Lm;0;L; 0078;;;;N;;;;; +02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L; 0295;;;;N;;;;; +02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;; +02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EC;MODIFIER LETTER VOICING;Lm;0;ON;;;;;N;;;;; +02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;; +02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;; +02EF;MODIFIER LETTER LOW DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F0;MODIFIER LETTER LOW UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F1;MODIFIER LETTER LOW LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F2;MODIFIER LETTER LOW RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F3;MODIFIER LETTER LOW RING;Sk;0;ON;;;;;N;;;;; +02F4;MODIFIER LETTER MIDDLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;; +02F5;MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;; +02F6;MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT;Sk;0;ON;;;;;N;;;;; +02F7;MODIFIER LETTER LOW TILDE;Sk;0;ON;;;;;N;;;;; +02F8;MODIFIER LETTER RAISED COLON;Sk;0;ON;;;;;N;;;;; +02F9;MODIFIER LETTER BEGIN HIGH TONE;Sk;0;ON;;;;;N;;;;; +02FA;MODIFIER LETTER END HIGH TONE;Sk;0;ON;;;;;N;;;;; +02FB;MODIFIER LETTER BEGIN LOW TONE;Sk;0;ON;;;;;N;;;;; +02FC;MODIFIER LETTER END LOW TONE;Sk;0;ON;;;;;N;;;;; +02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;; +02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;; +02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;; +0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;Varia;;; +0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;Oxia, Tonos;;; +0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;; +0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;; +0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;; +0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;; +0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;Vrachy;;; +0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;; +0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;Dialytika;;; +0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;; +030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;; +030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;; +030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;; +030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;; +030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;; +030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;; +0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;; +0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;; +0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;; +0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;Psili;;; +0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;Dasia;;; +0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;; +0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;; +0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;; +0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;; +0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;; +031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;; +031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;; +031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;; +031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;; +031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;; +031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;; +0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;; +0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;; +0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;; +0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;; +0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;; +0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;; +0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;; +0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;; +0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;; +0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;; +032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;; +032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;; +032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;; +032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;; +032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;; +032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;; +0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;; +0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;; +0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;; +0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;; +0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;; +0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;; +0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;; +0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;; +0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;; +0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;; +033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;; +033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;; +033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;; +033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;; +033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;; +033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;; +0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;Vietnamese;;; +0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;Vietnamese;;; +0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;; +0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;; +0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;; +0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399 +0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;; +0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;; +034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;; +034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;; +034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;; +034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;; +0350;COMBINING RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +0351;COMBINING LEFT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;; +0352;COMBINING FERMATA;Mn;230;NSM;;;;;N;;;;; +0353;COMBINING X BELOW;Mn;220;NSM;;;;;N;;;;; +0354;COMBINING LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0355;COMBINING RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0356;COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0357;COMBINING RIGHT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;; +0358;COMBINING DOT ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;; +0359;COMBINING ASTERISK BELOW;Mn;220;NSM;;;;;N;;;;; +035A;COMBINING DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;; +035B;COMBINING ZIGZAG ABOVE;Mn;230;NSM;;;;;N;;;;; +035C;COMBINING DOUBLE BREVE BELOW;Mn;233;NSM;;;;;N;;;;; +035D;COMBINING DOUBLE BREVE;Mn;234;NSM;;;;;N;;;;; +035E;COMBINING DOUBLE MACRON;Mn;234;NSM;;;;;N;;;;; +035F;COMBINING DOUBLE MACRON BELOW;Mn;233;NSM;;;;;N;;;;; +0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;; +0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;; +0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;; +0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;; +0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;; +0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;; +0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;; +0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;; +0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;; +0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;; +036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;; +036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;; +036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;; +036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;; +036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;; +036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;; +0370;GREEK CAPITAL LETTER HETA;Lu;0;L;;;;;N;;;;0371; +0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370 +0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373; +0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372 +0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;Dexia keraia;;; +0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;Aristeri keraia;;; +0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377; +0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376 +037A;GREEK YPOGEGRAMMENI;Lm;0;L; 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;; +037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD +037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE +037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF +037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;Erotimatiko;;; +0384;GREEK TONOS;Sk;0;ON; 0020 0301;;;;N;GREEK SPACING TONOS;;;; +0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;; +0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC; +0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;; +0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD; +0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE; +038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF; +038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC; +038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD; +038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE; +0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;; +0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1; +0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2; +0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3; +0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4; +0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5; +0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6; +0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7; +0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8; +0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9; +039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA; +039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB; +039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC; +039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD; +039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE; +039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF; +03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0; +03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1; +03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3; +03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4; +03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5; +03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6; +03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7; +03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8; +03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9; +03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA; +03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB; +03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386 +03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388 +03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389 +03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A +03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;; +03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391 +03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392 +03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393 +03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394 +03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395 +03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396 +03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397 +03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398 +03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399 +03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A +03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B +03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C +03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D +03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E +03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F +03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0 +03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1 +03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4 +03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5 +03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6 +03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7 +03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8 +03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9 +03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA +03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB +03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C +03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E +03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F +03CF;GREEK CAPITAL KAI SYMBOL;Lu;0;L;;;;;N;;;;03D7; +03D0;GREEK BETA SYMBOL;Ll;0;L; 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392 +03D1;GREEK THETA SYMBOL;Ll;0;L; 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398 +03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L; 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;; +03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;; +03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;; +03D5;GREEK PHI SYMBOL;Ll;0;L; 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6 +03D6;GREEK PI SYMBOL;Ll;0;L; 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0 +03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF +03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;*;;03D9; +03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;*;03D8;;03D8 +03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB; +03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA +03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD; +03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC +03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF; +03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE +03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1; +03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0 +03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3; +03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2 +03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5; +03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4 +03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7; +03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6 +03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9; +03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8 +03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB; +03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA +03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED; +03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC +03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF; +03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE +03F0;GREEK KAPPA SYMBOL;Ll;0;L; 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A +03F1;GREEK RHO SYMBOL;Ll;0;L; 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1 +03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L; 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9 +03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;; +03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L; 0398;;;;N;;;;03B8; +03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L; 03B5;;;;N;;;0395;;0395 +03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;; +03F7;GREEK CAPITAL LETTER SHO;Lu;0;L;;;;;N;;;;03F8; +03F8;GREEK SMALL LETTER SHO;Ll;0;L;;;;;N;;;03F7;;03F7 +03F9;GREEK CAPITAL LUNATE SIGMA SYMBOL;Lu;0;L; 03A3;;;;N;;;;03F2; +03FA;GREEK CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;03FB; +03FB;GREEK SMALL LETTER SAN;Ll;0;L;;;;;N;;;03FA;;03FA +03FC;GREEK RHO WITH STROKE SYMBOL;Ll;0;L;;;;;N;;;;; +03FD;GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037B; +03FE;GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037C; +03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D; +0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450; +0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451; +0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;Serbocroatian;;0452; +0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453; +0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454; +0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455; +0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456; +0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;Ukrainian;;0457; +0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458; +0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459; +040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A; +040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;Serbocroatian;;045B; +040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C; +040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D; +040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;Byelorussian;;045E; +040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F; +0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430; +0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431; +0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432; +0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433; +0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434; +0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435; +0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436; +0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437; +0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438; +0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439; +041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A; +041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B; +041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C; +041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D; +041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E; +041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F; +0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440; +0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441; +0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442; +0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443; +0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444; +0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445; +0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446; +0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447; +0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448; +0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449; +042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A; +042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B; +042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C; +042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D; +042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E; +042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F; +0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410 +0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411 +0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412 +0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413 +0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414 +0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415 +0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416 +0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417 +0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418 +0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419 +043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A +043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B +043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C +043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D +043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E +043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F +0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420 +0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421 +0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422 +0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423 +0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424 +0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425 +0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426 +0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427 +0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428 +0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429 +044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A +044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B +044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C +044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D +044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E +044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F +0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400 +0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401 +0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;Serbocroatian;0402;;0402 +0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403 +0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404 +0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405 +0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406 +0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;Ukrainian;0407;;0407 +0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408 +0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409 +045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A +045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;Serbocroatian;040B;;040B +045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C +045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D +045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;Byelorussian;040E;;040E +045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F +0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461; +0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460 +0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463; +0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462 +0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465; +0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464 +0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467; +0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466 +0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469; +0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468 +046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B; +046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A +046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D; +046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C +046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F; +046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E +0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471; +0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470 +0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473; +0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472 +0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475; +0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474 +0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477; +0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476 +0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479; +0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478 +047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B; +047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A +047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D; +047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C +047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F; +047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E +0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481; +0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480 +0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;; +0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;; +0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;; +0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;; +0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;; +0487;COMBINING CYRILLIC POKRYTIE;Mn;230;NSM;;;;;N;;;;; +0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;; +0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B; +048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A +048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D; +048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C +048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F; +048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E +0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491; +0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490 +0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493; +0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492 +0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495; +0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494 +0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497; +0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496 +0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499; +0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498 +049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B; +049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A +049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D; +049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C +049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F; +049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E +04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1; +04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0 +04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3; +04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2 +04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5; +04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4 +04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;Abkhasian;;04A7; +04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;Abkhasian;04A6;;04A6 +04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9; +04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8 +04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB; +04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA +04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD; +04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC +04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF; +04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE +04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1; +04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0 +04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3; +04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2 +04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;Abkhasian;;04B5; +04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;Abkhasian;04B4;;04B4 +04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7; +04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6 +04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9; +04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8 +04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB; +04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA +04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD; +04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC +04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF; +04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE +04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;04CF; +04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2; +04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1 +04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4; +04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3 +04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6; +04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5 +04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8; +04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7 +04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA; +04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9 +04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC; +04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB +04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE; +04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD +04CF;CYRILLIC SMALL LETTER PALOCHKA;Ll;0;L;;;;;N;;;04C0;;04C0 +04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1; +04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0 +04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3; +04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2 +04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5; +04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4 +04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7; +04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6 +04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9; +04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8 +04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB; +04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA +04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD; +04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC +04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF; +04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE +04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1; +04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0 +04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3; +04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2 +04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5; +04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4 +04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7; +04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6 +04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9; +04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8 +04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB; +04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA +04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED; +04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC +04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF; +04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE +04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1; +04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0 +04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3; +04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2 +04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5; +04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4 +04F6;CYRILLIC CAPITAL LETTER GHE WITH DESCENDER;Lu;0;L;;;;;N;;;;04F7; +04F7;CYRILLIC SMALL LETTER GHE WITH DESCENDER;Ll;0;L;;;;;N;;;04F6;;04F6 +04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9; +04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8 +04FA;CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK;Lu;0;L;;;;;N;;;;04FB; +04FB;CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK;Ll;0;L;;;;;N;;;04FA;;04FA +04FC;CYRILLIC CAPITAL LETTER HA WITH HOOK;Lu;0;L;;;;;N;;;;04FD; +04FD;CYRILLIC SMALL LETTER HA WITH HOOK;Ll;0;L;;;;;N;;;04FC;;04FC +04FE;CYRILLIC CAPITAL LETTER HA WITH STROKE;Lu;0;L;;;;;N;;;;04FF; +04FF;CYRILLIC SMALL LETTER HA WITH STROKE;Ll;0;L;;;;;N;;;04FE;;04FE +0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501; +0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500 +0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503; +0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502 +0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505; +0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504 +0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507; +0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506 +0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509; +0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508 +050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B; +050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A +050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D; +050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C +050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F; +050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E +0510;CYRILLIC CAPITAL LETTER REVERSED ZE;Lu;0;L;;;;;N;;;;0511; +0511;CYRILLIC SMALL LETTER REVERSED ZE;Ll;0;L;;;;;N;;;0510;;0510 +0512;CYRILLIC CAPITAL LETTER EL WITH HOOK;Lu;0;L;;;;;N;;;;0513; +0513;CYRILLIC SMALL LETTER EL WITH HOOK;Ll;0;L;;;;;N;;;0512;;0512 +0514;CYRILLIC CAPITAL LETTER LHA;Lu;0;L;;;;;N;;;;0515; +0515;CYRILLIC SMALL LETTER LHA;Ll;0;L;;;;;N;;;0514;;0514 +0516;CYRILLIC CAPITAL LETTER RHA;Lu;0;L;;;;;N;;;;0517; +0517;CYRILLIC SMALL LETTER RHA;Ll;0;L;;;;;N;;;0516;;0516 +0518;CYRILLIC CAPITAL LETTER YAE;Lu;0;L;;;;;N;;;;0519; +0519;CYRILLIC SMALL LETTER YAE;Ll;0;L;;;;;N;;;0518;;0518 +051A;CYRILLIC CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;051B; +051B;CYRILLIC SMALL LETTER QA;Ll;0;L;;;;;N;;;051A;;051A +051C;CYRILLIC CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;051D; +051D;CYRILLIC SMALL LETTER WE;Ll;0;L;;;;;N;;;051C;;051C +051E;CYRILLIC CAPITAL LETTER ALEUT KA;Lu;0;L;;;;;N;;;;051F; +051F;CYRILLIC SMALL LETTER ALEUT KA;Ll;0;L;;;;;N;;;051E;;051E +0520;CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0521; +0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520 +0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523; +0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522 +0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561; +0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562; +0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563; +0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564; +0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565; +0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566; +0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567; +0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568; +0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569; +053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A; +053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B; +053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C; +053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D; +053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E; +053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F; +0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570; +0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571; +0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572; +0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573; +0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574; +0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575; +0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576; +0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577; +0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578; +0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579; +054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A; +054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B; +054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C; +054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D; +054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E; +054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F; +0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580; +0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581; +0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582; +0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583; +0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584; +0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585; +0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586; +0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;; +055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;; +055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;; +055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;; +055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;; +055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;; +0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531 +0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532 +0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533 +0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534 +0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535 +0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536 +0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537 +0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538 +0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539 +056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A +056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B +056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C +056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D +056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E +056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F +0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540 +0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541 +0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542 +0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543 +0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544 +0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545 +0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546 +0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547 +0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548 +0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549 +057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A +057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B +057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C +057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D +057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E +057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F +0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550 +0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551 +0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552 +0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553 +0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554 +0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555 +0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556 +0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L; 0565 0582;;;;N;;;;; +0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;; +058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;; +0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;; +0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;; +0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;; +0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;; +0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;; +0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;*;;; +0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;; +0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;*;;; +0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;; +059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;; +059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;; +059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;; +059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;; +059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;; +059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;; +05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;; +05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;; +05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;; +05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;; +05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;; +05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;*;;; +05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;; +05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;; +05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;*;;; +05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;; +05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;*;;; +05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;; +05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;; +05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;; +05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;; +05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;; +05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;; +05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;; +05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;; +05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;; +05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;; +05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;; +05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;; +05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;; +05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;; +05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;; +05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;; +05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;; +05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;or shuruq;;; +05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;*;;; +05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;; +05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;; +05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;*;;; +05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;; +05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;; +05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;*;;; +05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;; +05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;; +05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;; +05C7;HEBREW POINT QAMATS QATAN;Mn;18;NSM;;;;;N;;;;; +05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;; +05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;; +05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;; +05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;; +05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;; +05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;; +05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;; +05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;; +05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;; +05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;; +05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;; +05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;; +05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;; +05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;; +05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;; +05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;; +05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;; +05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;; +05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;; +05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;; +05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;; +05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;; +05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;; +05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;; +05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;; +05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;; +05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;; +05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;; +05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;; +0600;ARABIC NUMBER SIGN;Cf;0;AN;;;;;N;;;;; +0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;; +0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;; +0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;; +0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;; +0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;; +0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;; +0609;ARABIC-INDIC PER MILLE SIGN;Po;0;ET;;;;;N;;;;; +060A;ARABIC-INDIC PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; +060B;AFGHANI SIGN;Sc;0;AL;;;;;N;;;;; +060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;; +060D;ARABIC DATE SEPARATOR;Po;0;AL;;;;;N;;;;; +060E;ARABIC POETIC VERSE SIGN;So;0;ON;;;;;N;;;;; +060F;ARABIC SIGN MISRA;So;0;ON;;;;;N;;;;; +0610;ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM;Mn;230;NSM;;;;;N;;;;; +0611;ARABIC SIGN ALAYHE ASSALLAM;Mn;230;NSM;;;;;N;;;;; +0612;ARABIC SIGN RAHMATULLAH ALAYHE;Mn;230;NSM;;;;;N;;;;; +0613;ARABIC SIGN RADI ALLAHOU ANHU;Mn;230;NSM;;;;;N;;;;; +0614;ARABIC SIGN TAKHALLUS;Mn;230;NSM;;;;;N;;;;; +0615;ARABIC SMALL HIGH TAH;Mn;230;NSM;;;;;N;;;;; +0616;ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH;Mn;230;NSM;;;;;N;;;;; +0617;ARABIC SMALL HIGH ZAIN;Mn;230;NSM;;;;;N;;;;; +0618;ARABIC SMALL FATHA;Mn;30;NSM;;;;;N;;;;; +0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;; +061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;; +061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;; +061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;; +061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;; +0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;; +0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;; +0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;; +0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;; +0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;; +0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;; +0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;; +0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;; +0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;; +062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;; +062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;; +062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;; +062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;; +062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;; +062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;; +0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;; +0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;; +0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;; +0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;; +0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;; +0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;; +0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;; +0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;; +0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;; +063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;; +063B;ARABIC LETTER KEHEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +063C;ARABIC LETTER KEHEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +063D;ARABIC LETTER FARSI YEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +063E;ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +063F;ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;; +0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;; +0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;; +0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;; +0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;; +0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;; +0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;; +0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;; +0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;; +064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;; +064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;; +064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;; +064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;; +064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;; +064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;; +0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;; +0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;; +0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;; +0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;; +0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;; +0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;; +0656;ARABIC SUBSCRIPT ALEF;Mn;220;NSM;;;;;N;;;;; +0657;ARABIC INVERTED DAMMA;Mn;230;NSM;;;;;N;;;;; +0658;ARABIC MARK NOON GHUNNA;Mn;230;NSM;;;;;N;;;;; +0659;ARABIC ZWARAKAY;Mn;230;NSM;;;;;N;;;;; +065A;ARABIC VOWEL SIGN SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;; +065B;ARABIC VOWEL SIGN INVERTED SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;; +065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;; +065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;; +065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;; +0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; +0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; +0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; +0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; +0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; +0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; +0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; +0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; +0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; +0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; +066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;; +066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;; +066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;; +066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;; +066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;; +066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;; +0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;; +0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;; +0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;; +0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;; +0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;; +0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL; 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;; +0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL; 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;; +0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL; 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;; +0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL; 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;; +0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;; +067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;; +067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;; +067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;; +067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;; +067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;; +067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;; +0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;; +0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;; +0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;; +0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;; +0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;; +0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;; +0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;; +0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;; +0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;; +0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;; +068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; +068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;; +068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;; +068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;; +068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;; +0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;; +0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;; +0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;; +0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;; +0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;; +0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;; +0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;; +0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;; +0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;; +069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;; +06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;; +06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;; +06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;; +06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;; +06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;; +06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;; +06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;; +06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;; +06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;; +06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;; +06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;; +06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;*;;; +06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;; +06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;; +06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;; +06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;; +06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;; +06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;; +06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;; +06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;; +06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;; +06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;; +06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;; +06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;; +06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;; +06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;; +06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;; +06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;; +06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;; +06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;; +06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;; +06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;; +06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;; +06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;; +06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;*;;; +06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;; +06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;; +06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;; +06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;; +06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;; +06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;; +06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;; +06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;; +06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;; +06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;; +06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;; +06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;; +06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;; +06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;; +06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;; +06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;; +06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;; +06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;; +06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;; +06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;; +06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;; +06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;; +06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;; +06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;; +06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;; +06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;; +06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;; +06EE;ARABIC LETTER DAL WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +06EF;ARABIC LETTER REH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;; +06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;; +06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;; +06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;; +06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;; +06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;; +06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;; +06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;; +06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;; +06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;; +06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;; +06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;; +06FF;ARABIC LETTER HEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;; +0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;; +0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;; +0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;; +0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;; +070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;; +070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;; +070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;; +070F;SYRIAC ABBREVIATION MARK;Cf;0;BN;;;;;N;;;;; +0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;; +0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;; +0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;; +0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;; +0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;; +0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;; +0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;; +0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;; +0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;; +071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;; +071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;; +071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;; +071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;; +071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;; +0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;; +0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;; +0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;; +0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;; +0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;; +0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;; +0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;; +0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;; +0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;; +0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;; +072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;; +072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;; +072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;; +072D;SYRIAC LETTER PERSIAN BHETH;Lo;0;AL;;;;;N;;;;; +072E;SYRIAC LETTER PERSIAN GHAMAL;Lo;0;AL;;;;;N;;;;; +072F;SYRIAC LETTER PERSIAN DHALATH;Lo;0;AL;;;;;N;;;;; +0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;; +0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;; +0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;; +0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;; +0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;; +073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;; +073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;; +073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;; +073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;; +0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;; +0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;; +0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;; +0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;; +0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;; +074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;; +074D;SYRIAC LETTER SOGDIAN ZHAIN;Lo;0;AL;;;;;N;;;;; +074E;SYRIAC LETTER SOGDIAN KHAPH;Lo;0;AL;;;;;N;;;;; +074F;SYRIAC LETTER SOGDIAN FE;Lo;0;AL;;;;;N;;;;; +0750;ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW;Lo;0;AL;;;;;N;;;;; +0751;ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0752;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0753;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0754;ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0755;ARABIC LETTER BEH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +0756;ARABIC LETTER BEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +0757;ARABIC LETTER HAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0758;ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0759;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; +075A;ARABIC LETTER DAL WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +075B;ARABIC LETTER REH WITH STROKE;Lo;0;AL;;;;;N;;;;; +075C;ARABIC LETTER SEEN WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +075D;ARABIC LETTER AIN WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +075E;ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE;Lo;0;AL;;;;;N;;;;; +075F;ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +0760;ARABIC LETTER FEH WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +0761;ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0762;ARABIC LETTER KEHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0763;ARABIC LETTER KEHEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0764;ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0765;ARABIC LETTER MEEM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0766;ARABIC LETTER MEEM WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +0767;ARABIC LETTER NOON WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +0768;ARABIC LETTER NOON WITH SMALL TAH;Lo;0;AL;;;;;N;;;;; +0769;ARABIC LETTER NOON WITH SMALL V;Lo;0;AL;;;;;N;;;;; +076A;ARABIC LETTER LAM WITH BAR;Lo;0;AL;;;;;N;;;;; +076B;ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +076C;ARABIC LETTER REH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;; +076D;ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +076E;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW;Lo;0;AL;;;;;N;;;;; +076F;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0770;ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0771;ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0772;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;; +0773;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0774;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +0775;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0776;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +0777;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;; +0778;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0779;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +077A;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +077B;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +077C;ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;; +077D;ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE;Lo;0;AL;;;;;N;;;;; +077E;ARABIC LETTER SEEN WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +077F;ARABIC LETTER KAF WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;; +0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;; +0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;; +0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;; +0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;; +0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;; +0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;; +0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;; +0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;; +0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;; +078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;; +078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;; +078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;; +078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;; +078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;; +078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;; +0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;; +0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;; +0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;; +0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;; +0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;; +0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;; +0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;; +0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;; +0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;; +0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;; +079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;; +079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;; +079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;; +079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;; +079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;; +079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;; +07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;; +07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;; +07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;; +07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;; +07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;; +07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;; +07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;; +07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;; +07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;; +07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;; +07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;; +07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;; +07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;; +07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;; +07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;; +07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;; +07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;; +07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;; +07C0;NKO DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;; +07C1;NKO DIGIT ONE;Nd;0;R;;1;1;1;N;;;;; +07C2;NKO DIGIT TWO;Nd;0;R;;2;2;2;N;;;;; +07C3;NKO DIGIT THREE;Nd;0;R;;3;3;3;N;;;;; +07C4;NKO DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;; +07C5;NKO DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;; +07C6;NKO DIGIT SIX;Nd;0;R;;6;6;6;N;;;;; +07C7;NKO DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;; +07C8;NKO DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;; +07C9;NKO DIGIT NINE;Nd;0;R;;9;9;9;N;;;;; +07CA;NKO LETTER A;Lo;0;R;;;;;N;;;;; +07CB;NKO LETTER EE;Lo;0;R;;;;;N;;;;; +07CC;NKO LETTER I;Lo;0;R;;;;;N;;;;; +07CD;NKO LETTER E;Lo;0;R;;;;;N;;;;; +07CE;NKO LETTER U;Lo;0;R;;;;;N;;;;; +07CF;NKO LETTER OO;Lo;0;R;;;;;N;;;;; +07D0;NKO LETTER O;Lo;0;R;;;;;N;;;;; +07D1;NKO LETTER DAGBASINNA;Lo;0;R;;;;;N;;;;; +07D2;NKO LETTER N;Lo;0;R;;;;;N;;;;; +07D3;NKO LETTER BA;Lo;0;R;;;;;N;;;;; +07D4;NKO LETTER PA;Lo;0;R;;;;;N;;;;; +07D5;NKO LETTER TA;Lo;0;R;;;;;N;;;;; +07D6;NKO LETTER JA;Lo;0;R;;;;;N;;;;; +07D7;NKO LETTER CHA;Lo;0;R;;;;;N;;;;; +07D8;NKO LETTER DA;Lo;0;R;;;;;N;;;;; +07D9;NKO LETTER RA;Lo;0;R;;;;;N;;;;; +07DA;NKO LETTER RRA;Lo;0;R;;;;;N;;;;; +07DB;NKO LETTER SA;Lo;0;R;;;;;N;;;;; +07DC;NKO LETTER GBA;Lo;0;R;;;;;N;;;;; +07DD;NKO LETTER FA;Lo;0;R;;;;;N;;;;; +07DE;NKO LETTER KA;Lo;0;R;;;;;N;;;;; +07DF;NKO LETTER LA;Lo;0;R;;;;;N;;;;; +07E0;NKO LETTER NA WOLOSO;Lo;0;R;;;;;N;;;;; +07E1;NKO LETTER MA;Lo;0;R;;;;;N;;;;; +07E2;NKO LETTER NYA;Lo;0;R;;;;;N;;;;; +07E3;NKO LETTER NA;Lo;0;R;;;;;N;;;;; +07E4;NKO LETTER HA;Lo;0;R;;;;;N;;;;; +07E5;NKO LETTER WA;Lo;0;R;;;;;N;;;;; +07E6;NKO LETTER YA;Lo;0;R;;;;;N;;;;; +07E7;NKO LETTER NYA WOLOSO;Lo;0;R;;;;;N;;;;; +07E8;NKO LETTER JONA JA;Lo;0;R;;;;;N;;;;; +07E9;NKO LETTER JONA CHA;Lo;0;R;;;;;N;;;;; +07EA;NKO LETTER JONA RA;Lo;0;R;;;;;N;;;;; +07EB;NKO COMBINING SHORT HIGH TONE;Mn;230;NSM;;;;;N;;;;; +07EC;NKO COMBINING SHORT LOW TONE;Mn;230;NSM;;;;;N;;;;; +07ED;NKO COMBINING SHORT RISING TONE;Mn;230;NSM;;;;;N;;;;; +07EE;NKO COMBINING LONG DESCENDING TONE;Mn;230;NSM;;;;;N;;;;; +07EF;NKO COMBINING LONG HIGH TONE;Mn;230;NSM;;;;;N;;;;; +07F0;NKO COMBINING LONG LOW TONE;Mn;230;NSM;;;;;N;;;;; +07F1;NKO COMBINING LONG RISING TONE;Mn;230;NSM;;;;;N;;;;; +07F2;NKO COMBINING NASALIZATION MARK;Mn;220;NSM;;;;;N;;;;; +07F3;NKO COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +07F4;NKO HIGH TONE APOSTROPHE;Lm;0;R;;;;;N;;;;; +07F5;NKO LOW TONE APOSTROPHE;Lm;0;R;;;;;N;;;;; +07F6;NKO SYMBOL OO DENNEN;So;0;ON;;;;;N;;;;; +07F7;NKO SYMBOL GBAKURUNEN;Po;0;ON;;;;;N;;;;; +07F8;NKO COMMA;Po;0;ON;;;;;N;;;;; +07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;; +0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0904;DEVANAGARI LETTER SHORT A;Lo;0;L;;;;;N;;;;; +0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;; +0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;; +0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;; +0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;; +0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;; +090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;; +090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;; +090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;; +090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;; +0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;; +0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;; +0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;; +0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;; +0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;; +0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;; +0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; +0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;; +0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; +0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; +091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;; +091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; +091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;; +091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; +091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; +091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; +0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; +0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; +0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;; +0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;; +0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;; +0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; +0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;; +0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;; +092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;; +092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; +092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;; +092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; +092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;; +092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;; +0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;; +0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;; +0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;; +0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; +0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;; +0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;; +0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; +0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; +0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;; +0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;; +093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;; +0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;; +094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;; +0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;; +0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;; +0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; +0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;; +0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;; +095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;; +095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;; +095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;; +095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;; +095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;; +095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;; +0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;; +0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;; +0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;; +097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;; +097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;; +097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;; +097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;; +0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;; +0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;; +0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;; +0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;; +0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;; +098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;; +098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;; +0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;; +0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;; +0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;; +0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;; +0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;; +0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;; +0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;; +0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;; +099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;; +099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;; +099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;; +099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;; +099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;; +099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;; +09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;; +09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;; +09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;; +09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;; +09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;; +09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;; +09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;; +09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;; +09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;; +09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;; +09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;; +09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;; +09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;; +09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;; +09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;; +09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;; +09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;; +09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;; +09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;; +09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;; +09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;; +09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +09BD;BENGALI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;; +09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;; +09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +09CE;BENGALI LETTER KHANDA TA;Lo;0;L;;;;;N;;;;; +09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;; +09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;; +09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;; +09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;Assamese;;; +09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;Assamese;;; +09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;; +09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1;N;;;;; +09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;2;N;;;;; +09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3;N;;;;; +09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;4;N;;;;; +09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;;N;;;;; +09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;; +09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;; +0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;; +0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;; +0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;; +0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;; +0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;; +0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;; +0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;; +0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;; +0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;; +0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;; +0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;; +0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;; +0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;; +0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;; +0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;; +0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;; +0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;; +0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;; +0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;; +0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;; +0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;; +0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;; +0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;; +0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;; +0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;; +0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;; +0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;; +0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;; +0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;; +0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;; +0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;; +0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;; +0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;; +0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;; +0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;; +0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;; +0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;; +0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0A51;GURMUKHI SIGN UDAAT;Mn;0;NSM;;;;;N;;;;; +0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;; +0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;; +0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;; +0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;; +0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;; +0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;; +0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;; +0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;; +0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;; +0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;; +0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;; +0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;; +0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;; +0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;; +0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;; +0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;; +0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;; +0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0A8C;GUJARATI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;; +0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;; +0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;; +0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;; +0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;; +0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;; +0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;; +0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;; +0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;; +0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;; +0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;; +0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;; +0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;; +0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;; +0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;; +0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;; +0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;; +0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;; +0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;; +0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;; +0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;; +0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;; +0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;; +0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;; +0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;; +0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;; +0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;; +0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;; +0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;; +0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;; +0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;; +0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;; +0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;; +0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0AE1;GUJARATI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0AE2;GUJARATI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0AE3;GUJARATI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;; +0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;; +0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;; +0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;; +0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;; +0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;; +0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;; +0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;; +0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;; +0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;; +0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;; +0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;; +0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;; +0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;; +0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;; +0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;; +0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;; +0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;; +0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;; +0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;; +0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;; +0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;; +0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;; +0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;; +0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;; +0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;; +0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;; +0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;; +0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;; +0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;; +0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;; +0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;; +0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;; +0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;; +0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;; +0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;; +0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;; +0B35;ORIYA LETTER VA;Lo;0;L;;;;;N;;;;; +0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;; +0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;; +0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;; +0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;; +0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0B44;ORIYA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;; +0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;; +0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;; +0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;; +0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;; +0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;; +0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0B62;ORIYA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0B63;ORIYA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;; +0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;; +0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;; +0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;; +0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;; +0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;; +0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;; +0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;; +0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;; +0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;; +0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;; +0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;; +0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;; +0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;; +0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;; +0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;; +0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;; +0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;; +0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;; +0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;; +0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;; +0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;; +0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;; +0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;; +0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;; +0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;; +0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;; +0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;; +0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;; +0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;; +0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;; +0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;; +0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;; +0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;; +0BB6;TAMIL LETTER SHA;Lo;0;L;;;;;N;;;;; +0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;; +0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;; +0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;; +0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;; +0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;; +0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;; +0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0BD0;TAMIL OM;Lo;0;L;;;;;N;;;;; +0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0BE6;TAMIL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;; +0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;Naal;;; +0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;Maatham;;; +0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;Varudam;;; +0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;Patru;;; +0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;Varavu;;; +0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;Merpadi;;; +0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;Rupai;;; +0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;Enn;;; +0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; +0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;; +0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;; +0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;; +0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;; +0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;; +0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;; +0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;; +0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;; +0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;; +0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;; +0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;; +0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;; +0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;; +0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;; +0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;; +0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;; +0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;; +0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;; +0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;; +0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;; +0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;; +0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;; +0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;; +0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;; +0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;; +0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;; +0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;; +0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;; +0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;; +0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;; +0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;; +0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;; +0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;; +0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;; +0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;; +0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;; +0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;; +0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;; +0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;; +0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;; +0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;; +0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;; +0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;; +0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;; +0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;; +0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;; +0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;; +0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;; +0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;; +0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;; +0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;; +0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;; +0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0C63;TELUGU VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;; +0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;; +0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;; +0C7B;TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR;No;0;ON;;;;3;N;;;;; +0C7C;TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR;No;0;ON;;;;1;N;;;;; +0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;; +0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;; +0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;; +0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;; +0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;; +0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;; +0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;; +0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;; +0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;; +0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;; +0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;; +0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;; +0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;; +0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;; +0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;; +0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;; +0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;; +0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;; +0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;; +0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;; +0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;; +0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;; +0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;; +0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;; +0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;; +0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;; +0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;; +0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;; +0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;; +0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;; +0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;; +0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;; +0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;; +0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;; +0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;; +0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;; +0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;; +0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;; +0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;; +0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;; +0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;; +0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;; +0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;; +0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;; +0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;; +0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;; +0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;; +0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;; +0CBC;KANNADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0CBD;KANNADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0CBF;KANNADA VOWEL SIGN I;Mn;0;L;;;;;N;;;;; +0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;; +0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0CC6;KANNADA VOWEL SIGN E;Mn;0;L;;;;;N;;;;; +0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;; +0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;; +0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;; +0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;; +0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;; +0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0CE2;KANNADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0CE3;KANNADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0CF1;KANNADA SIGN JIHVAMULIYA;So;0;ON;;;;;N;;;;; +0CF2;KANNADA SIGN UPADHMANIYA;So;0;ON;;;;;N;;;;; +0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;; +0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;; +0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;; +0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;; +0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;; +0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;; +0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;; +0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;; +0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;; +0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;; +0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;; +0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;; +0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;; +0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;; +0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;; +0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;; +0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;; +0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;; +0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;; +0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;; +0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;; +0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;; +0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;; +0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;; +0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;; +0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;; +0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;; +0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;; +0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;; +0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;; +0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;; +0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;; +0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;; +0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;; +0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;; +0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;; +0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;; +0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;; +0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;; +0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;; +0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;; +0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;; +0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;; +0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;; +0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;; +0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;; +0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;; +0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;; +0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0D44;MALAYALAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;; +0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;; +0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;; +0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0D63;MALAYALAM VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0D70;MALAYALAM NUMBER TEN;No;0;L;;;;10;N;;;;; +0D71;MALAYALAM NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +0D72;MALAYALAM NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; +0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;; +0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;; +0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;; +0D7C;MALAYALAM LETTER CHILLU RR;Lo;0;L;;;;;N;;;;; +0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;; +0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;; +0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;; +0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;; +0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;; +0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;; +0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;; +0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;; +0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;; +0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;; +0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;; +0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;; +0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;; +0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;; +0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;; +0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;; +0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;; +0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;; +0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;; +0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;; +0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;; +0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;; +0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;; +0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;; +0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;; +0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;; +0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;; +0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;; +0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;; +0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;; +0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;; +0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;; +0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;; +0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;; +0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;; +0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;; +0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;; +0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;; +0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;; +0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;; +0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;; +0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;; +0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;; +0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;; +0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;; +0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;; +0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;; +0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;; +0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;; +0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;; +0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;; +0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;; +0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;; +0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;; +0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;; +0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;; +0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;; +0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;; +0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;; +0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;; +0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;; +0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;; +0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;; +0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;; +0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;; +0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;; +0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;; +0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;; +0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;; +0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;; +0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;; +0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;; +0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;; +0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;; +0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;; +0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;; +0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;; +0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;; +0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;; +0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;; +0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;; +0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;; +0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;; +0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;; +0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;; +0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;; +0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;; +0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;paiyan noi;;; +0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;; +0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;; +0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;; +0E33;THAI CHARACTER SARA AM;Lo;0;L; 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;; +0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;; +0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;; +0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;; +0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;sara uue;;; +0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;; +0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;; +0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;; +0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;; +0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;; +0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;; +0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;; +0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;sara ai mai muan;;; +0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;sara ai mai malai;;; +0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;lakkhang yao;;; +0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;mai yamok;;; +0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;mai taikhu;;; +0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;; +0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;; +0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;; +0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;; +0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;; +0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;nikkhahit;;; +0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;; +0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;; +0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;; +0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;; +0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;; +0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;; +0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;; +0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;; +0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;; +0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;; +0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;; +0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;; +0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;; +0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;; +0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;; +0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;; +0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;; +0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;; +0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;; +0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;; +0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;; +0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;; +0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;; +0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;; +0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;; +0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;; +0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;; +0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;; +0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;; +0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;; +0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;; +0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;; +0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;; +0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;; +0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;; +0EB3;LAO VOWEL SIGN AM;Lo;0;L; 0ECD 0EB2;;;;N;;;;; +0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;; +0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;; +0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;; +0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;; +0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;; +0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;; +0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;; +0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;; +0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;; +0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;; +0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;; +0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;; +0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;; +0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;; +0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;; +0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;; +0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;; +0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0EDC;LAO HO NO;Lo;0;L; 0EAB 0E99;;;;N;;;;; +0EDD;LAO HO MO;Lo;0;L; 0EAB 0EA1;;;;N;;;;; +0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;; +0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;ter yik go a thung;;; +0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;ter yik go wum nam chey ma;;; +0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;ter yik go wum ter tsek ma;;; +0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;yik go dun ma;;; +0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;yik go kab ma;;; +0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;yik go pur shey ma;;; +0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;yik go tsek shey ma;;; +0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;drul shey;;; +0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;kur yik go;;; +0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;ka sho yik go;;; +0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;tsek;;; +0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L; 0F0B;;;;N;;tsek tar;;; +0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;shey;;; +0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;nyi shey;;; +0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;tsek shey;;; +0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;nyi tsek shey;;; +0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;rinchen pung shey;;; +0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;gya tram shey;;; +0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;dzu ta me long chen;;; +0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;ter tsek;;; +0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;che ta;;; +0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;hlak ta;;; +0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;trachen char ta;;; +0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;kyu pa;;; +0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;dong tsu;;; +0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;deka chig;;; +0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;deka nyi;;; +0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;deka sum;;; +0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;dena chig;;; +0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;dena nyi;;; +0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;deka dena;;; +0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;; +0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;; +0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;; +0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;; +0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;; +0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;; +0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;; +0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;; +0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;; +0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;; +0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;du ta;;; +0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;nge zung nyi da;;; +0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;dzu ta shi mig chen;;; +0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;nge zung gor ta;;; +0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;che go;;; +0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;tsa tru;;; +0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;gug ta yun;;; +0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;gug ta ye;;; +0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;ang kang yun;;; +0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;ang kang ye;;; +0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;yar tse;;; +0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;mar tse;;; +0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;; +0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;; +0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;; +0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;; +0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;; +0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;; +0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;; +0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;; +0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;; +0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;; +0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;; +0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;; +0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;; +0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;; +0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;; +0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;; +0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;; +0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;; +0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;; +0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;; +0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;; +0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;; +0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;; +0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;; +0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;; +0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;; +0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;; +0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;; +0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;; +0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;; +0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;; +0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;; +0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;; +0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;*;;; +0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;; +0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;; +0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;; +0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;; +0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;; +0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;; +0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;; +0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;*;;; +0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;; +0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;; +0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;; +0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;; +0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;; +0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;; +0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;; +0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;; +0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM; 0FB2 0F81;;;;N;;;;; +0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;; +0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM; 0FB3 0F81;;;;N;;;;; +0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;; +0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;; +0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;; +0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;; +0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;je su nga ro;;; +0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;nam chey;;; +0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;; +0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;; +0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;nyi da na da;;; +0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;nan de;;; +0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;; +0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;; +0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;ji ta;;; +0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;yang ta;;; +0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;che tsa chen;;; +0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;chu chen;;; +0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;tru chen ging;;; +0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;tru me ging;;; +0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;; +0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;; +0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;; +0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;; +0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;; +0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;; +0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;; +0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;; +0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;; +0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;; +0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;; +0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;; +0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;; +0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;; +0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;; +0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;; +0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;; +0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;; +0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;; +0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;; +0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;; +0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;; +0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;; +0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;; +0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;; +0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;; +0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;; +0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;; +0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;*;;; +0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;; +0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;; +0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;; +0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;*;;; +0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;*;;; +0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;; +0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;; +0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;; +0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;; +0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;; +0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;; +0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;; +0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;*;;; +0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;*;;; +0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;*;;; +0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;kuruka;;; +0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;kuruka shi mik chen;;; +0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;; +0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;; +0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;chang tyu;;; +0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;bub chey;;; +0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;drilbu;;; +0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;dorje;;; +0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;pema den;;; +0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;dorje gya dram;;; +0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;phurba;;; +0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;norbu;;; +0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;norbu nyi khyi;;; +0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;norbu sum khyi;;; +0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;norbu shi khyi;;; +0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;dena deka;;; +0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;dena sum;;; +0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;ka shog gi go gyen;;; +0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;nyam yig gi go gyen;;; +0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;nyi tsek;;; +0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;da nying yik go dun ma;;; +0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;da nying yik go kab ma;;; +1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;; +1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;; +1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;; +1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;; +1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;; +1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;; +1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;; +1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;; +1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;; +1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;; +100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;; +100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;; +100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;; +100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;; +100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;; +100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;; +1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;; +1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;; +1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;; +1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;; +1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;; +1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;; +1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;; +1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;; +1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;; +1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;; +101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;; +101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;; +101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;; +101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;; +101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;; +101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;; +1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;; +1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;; +1022;MYANMAR LETTER SHAN A;Lo;0;L;;;;;N;;;;; +1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;; +1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;; +1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;; +1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;; +1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;; +1028;MYANMAR LETTER MON E;Lo;0;L;;;;;N;;;;; +1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;; +102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;; +102B;MYANMAR VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;; +102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +1033;MYANMAR VOWEL SIGN MON II;Mn;0;NSM;;;;;N;;;;; +1034;MYANMAR VOWEL SIGN MON O;Mn;0;NSM;;;;;N;;;;; +1035;MYANMAR VOWEL SIGN E ABOVE;Mn;0;NSM;;;;;N;;;;; +1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;; +1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;; +1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +103A;MYANMAR SIGN ASAT;Mn;9;NSM;;;;;N;;;;; +103B;MYANMAR CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;; +103C;MYANMAR CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;; +103D;MYANMAR CONSONANT SIGN MEDIAL WA;Mn;0;NSM;;;;;N;;;;; +103E;MYANMAR CONSONANT SIGN MEDIAL HA;Mn;0;NSM;;;;;N;;;;; +103F;MYANMAR LETTER GREAT SA;Lo;0;L;;;;;N;;;;; +1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;; +104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;; +104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;; +104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;; +104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;; +104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;; +1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;; +1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;; +1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +105A;MYANMAR LETTER MON NGA;Lo;0;L;;;;;N;;;;; +105B;MYANMAR LETTER MON JHA;Lo;0;L;;;;;N;;;;; +105C;MYANMAR LETTER MON BBA;Lo;0;L;;;;;N;;;;; +105D;MYANMAR LETTER MON BBE;Lo;0;L;;;;;N;;;;; +105E;MYANMAR CONSONANT SIGN MON MEDIAL NA;Mn;0;NSM;;;;;N;;;;; +105F;MYANMAR CONSONANT SIGN MON MEDIAL MA;Mn;0;NSM;;;;;N;;;;; +1060;MYANMAR CONSONANT SIGN MON MEDIAL LA;Mn;0;NSM;;;;;N;;;;; +1061;MYANMAR LETTER SGAW KAREN SHA;Lo;0;L;;;;;N;;;;; +1062;MYANMAR VOWEL SIGN SGAW KAREN EU;Mc;0;L;;;;;N;;;;; +1063;MYANMAR TONE MARK SGAW KAREN HATHI;Mc;0;L;;;;;N;;;;; +1064;MYANMAR TONE MARK SGAW KAREN KE PHO;Mc;0;L;;;;;N;;;;; +1065;MYANMAR LETTER WESTERN PWO KAREN THA;Lo;0;L;;;;;N;;;;; +1066;MYANMAR LETTER WESTERN PWO KAREN PWA;Lo;0;L;;;;;N;;;;; +1067;MYANMAR VOWEL SIGN WESTERN PWO KAREN EU;Mc;0;L;;;;;N;;;;; +1068;MYANMAR VOWEL SIGN WESTERN PWO KAREN UE;Mc;0;L;;;;;N;;;;; +1069;MYANMAR SIGN WESTERN PWO KAREN TONE-1;Mc;0;L;;;;;N;;;;; +106A;MYANMAR SIGN WESTERN PWO KAREN TONE-2;Mc;0;L;;;;;N;;;;; +106B;MYANMAR SIGN WESTERN PWO KAREN TONE-3;Mc;0;L;;;;;N;;;;; +106C;MYANMAR SIGN WESTERN PWO KAREN TONE-4;Mc;0;L;;;;;N;;;;; +106D;MYANMAR SIGN WESTERN PWO KAREN TONE-5;Mc;0;L;;;;;N;;;;; +106E;MYANMAR LETTER EASTERN PWO KAREN NNA;Lo;0;L;;;;;N;;;;; +106F;MYANMAR LETTER EASTERN PWO KAREN YWA;Lo;0;L;;;;;N;;;;; +1070;MYANMAR LETTER EASTERN PWO KAREN GHWA;Lo;0;L;;;;;N;;;;; +1071;MYANMAR VOWEL SIGN GEBA KAREN I;Mn;0;NSM;;;;;N;;;;; +1072;MYANMAR VOWEL SIGN KAYAH OE;Mn;0;NSM;;;;;N;;;;; +1073;MYANMAR VOWEL SIGN KAYAH U;Mn;0;NSM;;;;;N;;;;; +1074;MYANMAR VOWEL SIGN KAYAH EE;Mn;0;NSM;;;;;N;;;;; +1075;MYANMAR LETTER SHAN KA;Lo;0;L;;;;;N;;;;; +1076;MYANMAR LETTER SHAN KHA;Lo;0;L;;;;;N;;;;; +1077;MYANMAR LETTER SHAN GA;Lo;0;L;;;;;N;;;;; +1078;MYANMAR LETTER SHAN CA;Lo;0;L;;;;;N;;;;; +1079;MYANMAR LETTER SHAN ZA;Lo;0;L;;;;;N;;;;; +107A;MYANMAR LETTER SHAN NYA;Lo;0;L;;;;;N;;;;; +107B;MYANMAR LETTER SHAN DA;Lo;0;L;;;;;N;;;;; +107C;MYANMAR LETTER SHAN NA;Lo;0;L;;;;;N;;;;; +107D;MYANMAR LETTER SHAN PHA;Lo;0;L;;;;;N;;;;; +107E;MYANMAR LETTER SHAN FA;Lo;0;L;;;;;N;;;;; +107F;MYANMAR LETTER SHAN BA;Lo;0;L;;;;;N;;;;; +1080;MYANMAR LETTER SHAN THA;Lo;0;L;;;;;N;;;;; +1081;MYANMAR LETTER SHAN HA;Lo;0;L;;;;;N;;;;; +1082;MYANMAR CONSONANT SIGN SHAN MEDIAL WA;Mn;0;NSM;;;;;N;;;;; +1083;MYANMAR VOWEL SIGN SHAN AA;Mc;0;L;;;;;N;;;;; +1084;MYANMAR VOWEL SIGN SHAN E;Mc;0;L;;;;;N;;;;; +1085;MYANMAR VOWEL SIGN SHAN E ABOVE;Mn;0;NSM;;;;;N;;;;; +1086;MYANMAR VOWEL SIGN SHAN FINAL Y;Mn;0;NSM;;;;;N;;;;; +1087;MYANMAR SIGN SHAN TONE-2;Mc;0;L;;;;;N;;;;; +1088;MYANMAR SIGN SHAN TONE-3;Mc;0;L;;;;;N;;;;; +1089;MYANMAR SIGN SHAN TONE-5;Mc;0;L;;;;;N;;;;; +108A;MYANMAR SIGN SHAN TONE-6;Mc;0;L;;;;;N;;;;; +108B;MYANMAR SIGN SHAN COUNCIL TONE-2;Mc;0;L;;;;;N;;;;; +108C;MYANMAR SIGN SHAN COUNCIL TONE-3;Mc;0;L;;;;;N;;;;; +108D;MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE;Mn;220;NSM;;;;;N;;;;; +108E;MYANMAR LETTER RUMAI PALAUNG FA;Lo;0;L;;;;;N;;;;; +108F;MYANMAR SIGN RUMAI PALAUNG TONE-5;Mc;0;L;;;;;N;;;;; +1090;MYANMAR SHAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1091;MYANMAR SHAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1092;MYANMAR SHAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1093;MYANMAR SHAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1094;MYANMAR SHAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1095;MYANMAR SHAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1096;MYANMAR SHAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;; +109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;; +10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;Khutsuri;;2D00; +10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;Khutsuri;;2D01; +10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;Khutsuri;;2D02; +10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;Khutsuri;;2D03; +10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;Khutsuri;;2D04; +10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;Khutsuri;;2D05; +10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;Khutsuri;;2D06; +10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;Khutsuri;;2D07; +10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;Khutsuri;;2D08; +10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;Khutsuri;;2D09; +10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;Khutsuri;;2D0A; +10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;Khutsuri;;2D0B; +10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;Khutsuri;;2D0C; +10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;Khutsuri;;2D0D; +10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;Khutsuri;;2D0E; +10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;Khutsuri;;2D0F; +10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;Khutsuri;;2D10; +10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;Khutsuri;;2D11; +10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;Khutsuri;;2D12; +10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;Khutsuri;;2D13; +10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;Khutsuri;;2D14; +10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;Khutsuri;;2D15; +10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;Khutsuri;;2D16; +10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;Khutsuri;;2D17; +10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;Khutsuri;;2D18; +10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;Khutsuri;;2D19; +10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;Khutsuri;;2D1A; +10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;Khutsuri;;2D1B; +10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;Khutsuri;;2D1C; +10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;Khutsuri;;2D1D; +10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;Khutsuri;;2D1E; +10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;Khutsuri;;2D1F; +10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;Khutsuri;;2D20; +10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;Khutsuri;;2D21; +10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;Khutsuri;;2D22; +10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;Khutsuri;;2D23; +10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;Khutsuri;;2D24; +10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;Khutsuri;;2D25; +10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;; +10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;; +10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;; +10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;; +10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;; +10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;; +10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;; +10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;; +10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;; +10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;; +10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;; +10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;; +10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;; +10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;; +10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;; +10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;; +10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;; +10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;; +10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;; +10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;; +10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;; +10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;; +10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;; +10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;; +10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;; +10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;; +10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;; +10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;; +10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;; +10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;; +10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;; +10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;; +10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;; +10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;; +10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;; +10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;; +10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;; +10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;; +10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;; +10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;; +10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;; +10F9;GEORGIAN LETTER TURNED GAN;Lo;0;L;;;;;N;;;;; +10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;; +10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L; 10DC;;;;N;;;;; +1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; +1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; +1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; +1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; +1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;dd *;;; +1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;r *;;; +1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; +1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; +1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;bb *;;; +1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;s *;;; +110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; +110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;; +110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; +110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;jj *;;; +110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; +110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; +1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; +1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; +1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; +1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; +1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;; +1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; +111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; +111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;; +1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; +1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; +1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;; +112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;; +112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;; +112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; +1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;; +1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; +1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;; +1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;; +113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; +113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;; +113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;; +113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;; +1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;; +1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;; +1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;; +1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;; +1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;; +114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;; +114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;; +114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;; +114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;; +114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;; +1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;; +1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;; +1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;; +1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;; +1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;; +1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;; +1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;; +1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;; +1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;; +1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;; +1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;; +1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;; +1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;; +1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;; +116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;; +116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;; +116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;; +116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;; +116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;; +116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;; +1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;; +1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;; +1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;; +1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;; +1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;; +1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;; +1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;; +1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;; +1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;; +1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;; +117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;; +117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;; +117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;; +117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;; +117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;; +117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;; +1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;; +1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;; +1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;; +1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;; +1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;; +1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;; +1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;; +1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;; +1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;; +1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;; +118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;; +118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;; +118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;; +118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;; +118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;; +118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;; +1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;; +1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;; +1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;; +1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;; +1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;; +1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;; +1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;; +1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;; +1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;; +1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;; +119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;; +119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;; +119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;; +119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;; +119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;; +119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;; +11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;; +11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;; +11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;; +11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; +11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; +11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;gs *;;; +11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; +11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;nj *;;; +11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;nh *;;; +11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; +11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;l *;;; +11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;lg *;;; +11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;lm *;;; +11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;lb *;;; +11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;ls *;;; +11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;lt *;;; +11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;lp *;;; +11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;lh *;;; +11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; +11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; +11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;bs *;;; +11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;s *;;; +11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; +11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;ng *;;; +11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; +11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; +11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; +11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; +11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; +11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; +11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;; +11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; +11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;; +11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;; +11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; +11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; +11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; +11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;; +11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;; +11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;; +11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;; +11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;; +11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;; +11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; +11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;; +11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;; +11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;; +11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;; +11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;; +11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;; +11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;; +11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;; +1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;; +1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;; +1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;; +1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;; +1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;; +1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;; +1207;ETHIOPIC SYLLABLE HOA;Lo;0;L;;;;;N;;;;; +1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;; +1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;; +120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;; +120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;; +120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;; +120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;; +120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;; +120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;; +1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;; +1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;; +1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;; +1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;; +1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;; +1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;; +1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;; +1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;; +1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;; +1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;; +121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;; +121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;; +121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;; +121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;; +121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;; +121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;; +1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;; +1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;; +1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;; +1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;; +1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;; +1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;; +1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;; +1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;; +1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;; +1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;; +122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;; +122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;; +122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;; +122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;; +122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;; +122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;; +1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;; +1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;; +1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;; +1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;; +1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;; +1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;; +1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;; +1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;; +1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;; +123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;; +123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; +123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;; +1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;; +1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;; +1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;; +1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;; +1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;; +1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;; +1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;; +1247;ETHIOPIC SYLLABLE QOA;Lo;0;L;;;;;N;;;;; +1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;; +124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;; +124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;; +124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;; +124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;; +1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;; +1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;; +1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;; +1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;; +1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;; +1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;; +1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;; +1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;; +125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;; +125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;; +125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;; +125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;; +1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;; +1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;; +1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;; +1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;; +1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;; +1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;; +1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;; +1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;; +1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;; +1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;; +126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;; +126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;; +126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;; +126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;; +126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;; +126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;; +1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;; +1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;; +1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;; +1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;; +1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;; +1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;; +1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;; +1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;; +1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;; +1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;; +127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;; +127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;; +127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;; +127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;; +127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;; +127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;; +1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;; +1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;; +1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;; +1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;; +1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;; +1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;; +1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;; +1287;ETHIOPIC SYLLABLE XOA;Lo;0;L;;;;;N;;;;; +1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;; +128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;; +128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;; +128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;; +128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;; +1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;; +1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;; +1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;; +1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;; +1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;; +1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;; +1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;; +1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;; +1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;; +1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;; +129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; +129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;; +129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;; +12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;; +12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;; +12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;; +12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;; +12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;; +12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;; +12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;; +12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;; +12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;; +12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;; +12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;; +12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;; +12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;; +12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;; +12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;; +12AF;ETHIOPIC SYLLABLE KOA;Lo;0;L;;;;;N;;;;; +12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;; +12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;; +12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;; +12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;; +12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;; +12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;; +12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;; +12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;; +12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;; +12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;; +12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;; +12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;; +12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;; +12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;; +12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;; +12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;; +12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;; +12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;; +12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;; +12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;; +12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;; +12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;; +12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;; +12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;; +12CF;ETHIOPIC SYLLABLE WOA;Lo;0;L;;;;;N;;;;; +12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;; +12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;; +12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;; +12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;; +12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;; +12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;; +12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;; +12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;; +12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; +12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;; +12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; +12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;; +12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; +12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;; +12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;; +12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;; +12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;; +12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;; +12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;; +12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;; +12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;; +12EF;ETHIOPIC SYLLABLE YOA;Lo;0;L;;;;;N;;;;; +12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;; +12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;; +12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;; +12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;; +12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;; +12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;; +12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;; +12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;; +12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;; +12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;; +12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;; +1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;; +1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;; +1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;; +1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;; +1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;; +1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;; +1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;; +1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;; +1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;; +1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;; +130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;; +130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;; +130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;; +130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;; +130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;; +130F;ETHIOPIC SYLLABLE GOA;Lo;0;L;;;;;N;;;;; +1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;; +1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;; +1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;; +1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;; +1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;; +1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;; +131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;; +131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +131F;ETHIOPIC SYLLABLE GGWAA;Lo;0;L;;;;;N;;;;; +1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;; +1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;; +1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;; +1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;; +1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;; +1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;; +1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;; +1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;; +1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;; +132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;; +132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;; +132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;; +1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;; +1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;; +1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;; +1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;; +1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;; +1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;; +1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;; +1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;; +1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;; +1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;; +133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;; +133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;; +133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;; +133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;; +133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;; +133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;; +1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;; +1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;; +1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;; +1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;; +1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;; +1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;; +1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;; +1347;ETHIOPIC SYLLABLE TZOA;Lo;0;L;;;;;N;;;;; +1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;; +1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;; +134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;; +134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;; +134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;; +134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;; +134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;; +134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;; +1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;; +1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;; +1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;; +1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;; +1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;; +1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;; +1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;; +1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;; +1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;; +1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;; +135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;; +135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;; +1360;ETHIOPIC SECTION MARK;So;0;L;;;;;N;;;;; +1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;; +1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;; +1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;; +1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;; +1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;; +1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;; +1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;; +1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +1369;ETHIOPIC DIGIT ONE;No;0;L;;;1;1;N;;;;; +136A;ETHIOPIC DIGIT TWO;No;0;L;;;2;2;N;;;;; +136B;ETHIOPIC DIGIT THREE;No;0;L;;;3;3;N;;;;; +136C;ETHIOPIC DIGIT FOUR;No;0;L;;;4;4;N;;;;; +136D;ETHIOPIC DIGIT FIVE;No;0;L;;;5;5;N;;;;; +136E;ETHIOPIC DIGIT SIX;No;0;L;;;6;6;N;;;;; +136F;ETHIOPIC DIGIT SEVEN;No;0;L;;;7;7;N;;;;; +1370;ETHIOPIC DIGIT EIGHT;No;0;L;;;8;8;N;;;;; +1371;ETHIOPIC DIGIT NINE;No;0;L;;;9;9;N;;;;; +1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;; +1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;; +1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;; +1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;; +1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;; +1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;; +1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;; +137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;; +137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; +1380;ETHIOPIC SYLLABLE SEBATBEIT MWA;Lo;0;L;;;;;N;;;;; +1381;ETHIOPIC SYLLABLE MWI;Lo;0;L;;;;;N;;;;; +1382;ETHIOPIC SYLLABLE MWEE;Lo;0;L;;;;;N;;;;; +1383;ETHIOPIC SYLLABLE MWE;Lo;0;L;;;;;N;;;;; +1384;ETHIOPIC SYLLABLE SEBATBEIT BWA;Lo;0;L;;;;;N;;;;; +1385;ETHIOPIC SYLLABLE BWI;Lo;0;L;;;;;N;;;;; +1386;ETHIOPIC SYLLABLE BWEE;Lo;0;L;;;;;N;;;;; +1387;ETHIOPIC SYLLABLE BWE;Lo;0;L;;;;;N;;;;; +1388;ETHIOPIC SYLLABLE SEBATBEIT FWA;Lo;0;L;;;;;N;;;;; +1389;ETHIOPIC SYLLABLE FWI;Lo;0;L;;;;;N;;;;; +138A;ETHIOPIC SYLLABLE FWEE;Lo;0;L;;;;;N;;;;; +138B;ETHIOPIC SYLLABLE FWE;Lo;0;L;;;;;N;;;;; +138C;ETHIOPIC SYLLABLE SEBATBEIT PWA;Lo;0;L;;;;;N;;;;; +138D;ETHIOPIC SYLLABLE PWI;Lo;0;L;;;;;N;;;;; +138E;ETHIOPIC SYLLABLE PWEE;Lo;0;L;;;;;N;;;;; +138F;ETHIOPIC SYLLABLE PWE;Lo;0;L;;;;;N;;;;; +1390;ETHIOPIC TONAL MARK YIZET;So;0;ON;;;;;N;;;;; +1391;ETHIOPIC TONAL MARK DERET;So;0;ON;;;;;N;;;;; +1392;ETHIOPIC TONAL MARK RIKRIK;So;0;ON;;;;;N;;;;; +1393;ETHIOPIC TONAL MARK SHORT RIKRIK;So;0;ON;;;;;N;;;;; +1394;ETHIOPIC TONAL MARK DIFAT;So;0;ON;;;;;N;;;;; +1395;ETHIOPIC TONAL MARK KENAT;So;0;ON;;;;;N;;;;; +1396;ETHIOPIC TONAL MARK CHIRET;So;0;ON;;;;;N;;;;; +1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;; +1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;; +1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;; +13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;; +13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;; +13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;; +13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;; +13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;; +13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;; +13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;; +13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;; +13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;; +13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;; +13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;; +13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;; +13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;; +13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;; +13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;; +13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;; +13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;; +13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;; +13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;; +13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;; +13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;; +13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;; +13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;; +13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;; +13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;; +13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;; +13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;; +13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;; +13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;; +13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;; +13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;; +13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;; +13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;; +13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;; +13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;; +13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;; +13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;; +13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;; +13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;; +13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;; +13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;; +13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;; +13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;; +13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;; +13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;; +13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;; +13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;; +13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;; +13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;; +13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;; +13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;; +13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;; +13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;; +13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;; +13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;; +13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;; +13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;; +13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;; +13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;; +13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;; +13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;; +13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;; +13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;; +13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;; +13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;; +13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;; +13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;; +13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;; +13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;; +13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;; +13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;; +13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;; +13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;; +13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;; +13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;; +13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;; +13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;; +13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;; +13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;; +13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;; +13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;; +13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;; +13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;; +13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;; +13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;; +1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;; +1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;; +1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;; +1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;; +1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;; +1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;; +1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;; +1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;; +1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;; +140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;; +140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;; +140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;; +140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;; +140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;; +140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;; +1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;; +1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;; +1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;; +1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;; +1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;; +1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;; +1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;; +1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;; +1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;; +1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;; +141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;; +141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;; +141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;; +141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;; +141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;; +1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;; +1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;; +1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;; +1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;; +1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;; +1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;; +1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;; +1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;; +1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;; +1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;; +142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;; +142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;; +142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;; +142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;; +142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;; +142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;; +1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;; +1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;; +1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;; +1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;; +1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;; +1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;; +1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;; +1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;; +1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;; +1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;; +143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;; +143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;; +143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;; +143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;; +143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;; +143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;; +1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;; +1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;; +1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;; +1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;; +1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;; +1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;; +1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;; +1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;; +1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;; +1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;; +144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;; +144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;; +144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;; +144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;; +144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;; +144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;; +1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;; +1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;; +1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;; +1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;; +1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;; +1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;; +1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;; +1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;; +1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;; +1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;; +145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;; +145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;; +145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;; +145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;; +145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;; +145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;; +1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;; +1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;; +1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;; +1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;; +1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;; +1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;; +1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;; +1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;; +1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;; +1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;; +146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;; +146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;; +146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;; +146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;; +146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;; +146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;; +1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;; +1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;; +1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;; +1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;; +1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;; +1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;; +1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;; +1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;; +1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;; +1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;; +147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;; +147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;; +147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;; +147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;; +147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;; +147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;; +1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;; +1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;; +1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;; +1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;; +1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;; +1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;; +1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;; +1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;; +1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;; +1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;; +148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;; +148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;; +148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;; +148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;; +148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;; +148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;; +1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;; +1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;; +1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;; +1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;; +1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;; +1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;; +1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;; +1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;; +1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;; +1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;; +149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;; +149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;; +149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;; +149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;; +149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;; +149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;; +14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;; +14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;; +14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;; +14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;; +14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;; +14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;; +14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;; +14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;; +14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;; +14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;; +14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;; +14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;; +14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;; +14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;; +14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;; +14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;; +14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;; +14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;; +14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;; +14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;; +14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;; +14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;; +14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;; +14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;; +14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;; +14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;; +14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;; +14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;; +14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;; +14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;; +14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;; +14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;; +14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;; +14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;; +14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;; +14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;; +14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;; +14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;; +14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;; +14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;; +14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;; +14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;; +14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;; +14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;; +14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;; +14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;; +14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;; +14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;; +14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;; +14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;; +14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;; +14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;; +14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;; +14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;; +14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;; +14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;; +14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;; +14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;; +14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;; +14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;; +14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;; +14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;; +14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;; +14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;; +14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;; +14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;; +14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;; +14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;; +14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;; +14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;; +14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;; +14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;; +14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;; +14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;; +14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;; +14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;; +14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;; +14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;; +14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;; +14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;; +14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;; +14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;; +14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;; +14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;; +14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;; +14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;; +14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;; +14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;; +14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;; +14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;; +14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;; +14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;; +14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;; +14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;; +14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;; +14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;; +1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;; +1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;; +1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;; +1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;; +1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;; +1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;; +1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;; +1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;; +1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;; +1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;; +150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;; +150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;; +150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;; +150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;; +150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;; +150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;; +1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;; +1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;; +1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;; +1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;; +1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;; +1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;; +1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;; +1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;; +1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;; +1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;; +151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;; +151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;; +151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;; +151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;; +151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;; +151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;; +1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;; +1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;; +1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;; +1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;; +1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;; +1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;; +1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;; +1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;; +1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;; +1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;; +152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;; +152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;; +152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;; +152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;; +152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;; +152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;; +1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;; +1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;; +1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;; +1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;; +1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;; +1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;; +1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;; +1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;; +1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;; +1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;; +153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;; +153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;; +153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;; +153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;; +153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;; +153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;; +1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;; +1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;; +1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;; +1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;; +1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;; +1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;; +1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;; +1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;; +1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;; +1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;; +154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;; +154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;; +154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;; +154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;; +154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;; +154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;; +1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;; +1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;; +1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;; +1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;; +1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;; +1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;; +1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;; +1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;; +1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;; +1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;; +155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;; +155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;; +155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;; +155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;; +155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;; +155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;; +1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;; +1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;; +1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;; +1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;; +1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;; +1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;; +1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;; +1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;; +1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;; +1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;; +156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;; +156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;; +156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;; +156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;; +156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;; +156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;; +1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;; +1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;; +1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;; +1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;; +1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;; +1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;; +1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;; +1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;; +1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;; +1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;; +157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;; +157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;; +157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;; +157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;; +157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;; +157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;; +1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;; +1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;; +1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;; +1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;; +1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;; +1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;; +1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;; +1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;; +1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;; +1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;; +158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;; +158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;; +158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;; +158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;; +158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;; +158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;; +1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;; +1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;; +1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;; +1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;; +1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;; +1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;; +1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;; +1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;; +1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;; +1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;; +159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;; +159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;; +159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;; +159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;; +159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;; +159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;; +15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;; +15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;; +15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;; +15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;; +15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;; +15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;; +15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;; +15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;; +15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;; +15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;; +15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;; +15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;; +15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;; +15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;; +15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;; +15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;; +15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;; +15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;; +15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;; +15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;; +15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;; +15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;; +15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;; +15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;; +15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;; +15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;; +15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;; +15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;; +15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;; +15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;; +15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;; +15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;; +15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;; +15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;; +15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;; +15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;; +15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;; +15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;; +15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;; +15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;; +15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;; +15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;; +15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;; +15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;; +15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;; +15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;; +15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;; +15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;; +15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;; +15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;; +15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;; +15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;; +15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;; +15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;; +15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;; +15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;; +15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;; +15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;; +15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;; +15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;; +15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;; +15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;; +15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;; +15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;; +15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;; +15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;; +15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;; +15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;; +15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;; +15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;; +15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;; +15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;; +15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;; +15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;; +15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;; +15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;; +15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;; +15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;; +15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;; +15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;; +15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;; +15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;; +15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;; +15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;; +15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;; +15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;; +15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;; +15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;; +15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;; +15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;; +15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;; +15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;; +15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;; +15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;; +15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;; +15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;; +1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;; +1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;; +1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;; +1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;; +1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;; +1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;; +1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;; +1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;; +1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;; +1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;; +160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;; +160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;; +160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;; +160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;; +160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;; +160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;; +1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;; +1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;; +1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;; +1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;; +1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;; +1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;; +1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;; +1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;; +1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;; +1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;; +161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;; +161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;; +161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;; +161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;; +161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;; +161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;; +1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;; +1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;; +1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;; +1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;; +1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;; +1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;; +1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;; +1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;; +1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;; +1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;; +162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;; +162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;; +162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;; +162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;; +162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;; +162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;; +1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;; +1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;; +1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;; +1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;; +1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;; +1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;; +1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;; +1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;; +1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;; +1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;; +163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;; +163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;; +163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;; +163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;; +163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;; +163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;; +1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;; +1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;; +1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;; +1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;; +1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;; +1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;; +1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;; +1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;; +1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;; +1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;; +164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;; +164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;; +164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;; +164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;; +164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;; +164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;; +1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;; +1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;; +1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;; +1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;; +1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;; +1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;; +1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;; +1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;; +1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;; +1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;; +165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;; +165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;; +165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;; +165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;; +165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;; +165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;; +1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;; +1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;; +1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;; +1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;; +1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;; +1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;; +1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;; +1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;; +1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;; +1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;; +166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;; +166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;; +166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;; +166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;; +166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;; +166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;; +1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;; +1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;; +1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;; +1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;; +1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;; +1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;; +1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;; +1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;; +1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;; +1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;; +1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;; +1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;; +1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;; +1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;; +1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;; +1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;; +1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;; +168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;; +168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;; +168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;; +168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;; +168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;; +168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;; +1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;; +1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;; +1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;; +1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;; +1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;; +1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;; +1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;; +1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;; +1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;; +1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;; +169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;; +169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;Y;;;;; +169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;Y;;;;; +16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;; +16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;; +16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;; +16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;; +16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;; +16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;; +16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;; +16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;; +16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;; +16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;; +16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;; +16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;; +16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;; +16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;; +16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;; +16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;; +16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;; +16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;; +16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;; +16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;; +16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;; +16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;; +16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;; +16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;; +16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;; +16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;; +16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;; +16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;; +16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;; +16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;; +16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;; +16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;; +16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;; +16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;; +16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;; +16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;; +16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;; +16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;; +16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;; +16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;; +16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;; +16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;; +16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;; +16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;; +16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;; +16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;; +16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;; +16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;; +16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;; +16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;; +16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;; +16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;; +16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;; +16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;; +16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;; +16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;; +16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;; +16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;; +16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;; +16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;; +16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;; +16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;; +16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;; +16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;; +16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;; +16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;; +16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;; +16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;; +16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;; +16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;; +16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;; +16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;; +16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;; +16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;; +16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;; +16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;; +16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;golden number 17;;; +16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;golden number 18;;; +16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;golden number 19;;; +1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;; +1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;; +1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;; +1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;; +1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;; +1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;; +1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;; +1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;; +1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;; +1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;; +170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;; +170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;; +170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;; +170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;; +170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;; +1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;; +1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;; +1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;; +1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;; +1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;; +1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;; +1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;; +1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;; +1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;; +1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;; +1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;; +1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;; +172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;; +172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;; +172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;; +172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;; +172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;; +172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;; +1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;; +1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;; +1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;; +1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;; +1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;; +1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;; +1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;; +1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;; +1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;; +1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;; +1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;; +1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;; +1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;; +174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;; +174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;; +174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;; +174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;; +174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;; +174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;; +1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;; +1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;; +1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;; +1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;; +1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;; +1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;; +1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;; +1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;; +1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;; +1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;; +1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;; +1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;; +176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;; +176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;; +176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;; +176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;; +176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;; +1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;; +1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;; +1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;; +1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;; +1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;; +1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;; +1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;; +1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;; +1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;; +1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;; +1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;; +178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;; +178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;; +178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;; +178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;; +178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;; +178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;; +1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;; +1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;; +1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;; +1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;; +1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;; +1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;; +1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;; +1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;; +1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;; +1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;; +179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;; +179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;; +179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;; +179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;; +179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;; +179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;; +17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;; +17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;; +17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;; +17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;*;;; +17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;*;;; +17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;; +17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;; +17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;; +17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;; +17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;; +17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;; +17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;; +17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;; +17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;; +17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;; +17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;; +17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;; +17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;; +17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;; +17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;; +17B4;KHMER VOWEL INHERENT AQ;Cf;0;L;;;;;N;;*;;; +17B5;KHMER VOWEL INHERENT AA;Cf;0;L;;;;;N;;*;;; +17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;; +17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;; +17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;; +17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;; +17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;; +17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;; +17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;; +17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;; +17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;; +17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;; +17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;; +17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;; +17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;; +17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;; +17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;; +17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;; +17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;; +17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;*;;; +17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;; +17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;; +17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;; +17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;; +17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;*;;; +17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;; +17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;; +17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;; +17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;; +17DD;KHMER SIGN ATTHACAN;Mn;230;NSM;;;;;N;;;;; +17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +17F0;KHMER SYMBOL LEK ATTAK SON;No;0;ON;;;;0;N;;;;; +17F1;KHMER SYMBOL LEK ATTAK MUOY;No;0;ON;;;;1;N;;;;; +17F2;KHMER SYMBOL LEK ATTAK PII;No;0;ON;;;;2;N;;;;; +17F3;KHMER SYMBOL LEK ATTAK BEI;No;0;ON;;;;3;N;;;;; +17F4;KHMER SYMBOL LEK ATTAK BUON;No;0;ON;;;;4;N;;;;; +17F5;KHMER SYMBOL LEK ATTAK PRAM;No;0;ON;;;;5;N;;;;; +17F6;KHMER SYMBOL LEK ATTAK PRAM-MUOY;No;0;ON;;;;6;N;;;;; +17F7;KHMER SYMBOL LEK ATTAK PRAM-PII;No;0;ON;;;;7;N;;;;; +17F8;KHMER SYMBOL LEK ATTAK PRAM-BEI;No;0;ON;;;;8;N;;;;; +17F9;KHMER SYMBOL LEK ATTAK PRAM-BUON;No;0;ON;;;;9;N;;;;; +1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;; +1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;; +1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;; +1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;; +1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;; +1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;; +1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;; +1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;; +1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;; +1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;; +180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;; +180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;; +180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;; +180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;; +180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;; +1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;; +1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;; +1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;; +1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;; +1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;; +1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;; +1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;; +1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;; +1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;; +1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;; +182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;; +182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;; +182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;; +182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;; +182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;; +182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;; +1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;; +1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;; +1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;; +1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;; +1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;; +1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;; +1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;; +1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;; +1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;; +1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;; +183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;; +183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;; +183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;; +183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;; +183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;; +183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;; +1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;; +1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;; +1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;; +1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;; +1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;; +1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;; +1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;; +1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;; +1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;; +1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;; +184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;; +184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;; +184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;; +184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;; +184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;; +184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;; +1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;; +1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;; +1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;; +1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;; +1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;; +1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;; +1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;; +1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;; +1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;; +1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;; +185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;; +185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;; +185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;; +185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;; +185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;; +185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;; +1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;; +1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;; +1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;; +1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;; +1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;; +1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;; +1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;; +1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;; +1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;; +1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;; +186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;; +186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;; +186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;; +186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;; +186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;; +186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;; +1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;; +1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;; +1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;; +1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;; +1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;; +1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;; +1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;; +1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;; +1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;; +1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;; +1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;; +1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;; +1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;; +1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;; +1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;; +1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;; +1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;; +1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;; +188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;; +188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;; +188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;; +188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;; +188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;; +188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;; +1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;; +1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;; +1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;; +1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;; +1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;; +1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;; +1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;; +1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;; +1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;; +189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;; +189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;; +189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;; +189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;; +189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;; +18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;; +18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;; +18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;; +18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;; +18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;; +18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;; +18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;; +18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;; +18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;; +18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;; +1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;; +1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;; +1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;; +1903;LIMBU LETTER GA;Lo;0;L;;;;;N;;;;; +1904;LIMBU LETTER GHA;Lo;0;L;;;;;N;;;;; +1905;LIMBU LETTER NGA;Lo;0;L;;;;;N;;;;; +1906;LIMBU LETTER CA;Lo;0;L;;;;;N;;;;; +1907;LIMBU LETTER CHA;Lo;0;L;;;;;N;;;;; +1908;LIMBU LETTER JA;Lo;0;L;;;;;N;;;;; +1909;LIMBU LETTER JHA;Lo;0;L;;;;;N;;;;; +190A;LIMBU LETTER YAN;Lo;0;L;;;;;N;;;;; +190B;LIMBU LETTER TA;Lo;0;L;;;;;N;;;;; +190C;LIMBU LETTER THA;Lo;0;L;;;;;N;;;;; +190D;LIMBU LETTER DA;Lo;0;L;;;;;N;;;;; +190E;LIMBU LETTER DHA;Lo;0;L;;;;;N;;;;; +190F;LIMBU LETTER NA;Lo;0;L;;;;;N;;;;; +1910;LIMBU LETTER PA;Lo;0;L;;;;;N;;;;; +1911;LIMBU LETTER PHA;Lo;0;L;;;;;N;;;;; +1912;LIMBU LETTER BA;Lo;0;L;;;;;N;;;;; +1913;LIMBU LETTER BHA;Lo;0;L;;;;;N;;;;; +1914;LIMBU LETTER MA;Lo;0;L;;;;;N;;;;; +1915;LIMBU LETTER YA;Lo;0;L;;;;;N;;;;; +1916;LIMBU LETTER RA;Lo;0;L;;;;;N;;;;; +1917;LIMBU LETTER LA;Lo;0;L;;;;;N;;;;; +1918;LIMBU LETTER WA;Lo;0;L;;;;;N;;;;; +1919;LIMBU LETTER SHA;Lo;0;L;;;;;N;;;;; +191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;; +191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;; +191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;; +1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;; +1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1923;LIMBU VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +1924;LIMBU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +1925;LIMBU VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1926;LIMBU VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +1927;LIMBU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1928;LIMBU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +1929;LIMBU SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;; +192A;LIMBU SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;; +192B;LIMBU SUBJOINED LETTER WA;Mc;0;L;;;;;N;;;;; +1930;LIMBU SMALL LETTER KA;Mc;0;L;;;;;N;;;;; +1931;LIMBU SMALL LETTER NGA;Mc;0;L;;;;;N;;;;; +1932;LIMBU SMALL LETTER ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1933;LIMBU SMALL LETTER TA;Mc;0;L;;;;;N;;;;; +1934;LIMBU SMALL LETTER NA;Mc;0;L;;;;;N;;;;; +1935;LIMBU SMALL LETTER PA;Mc;0;L;;;;;N;;;;; +1936;LIMBU SMALL LETTER MA;Mc;0;L;;;;;N;;;;; +1937;LIMBU SMALL LETTER RA;Mc;0;L;;;;;N;;;;; +1938;LIMBU SMALL LETTER LA;Mc;0;L;;;;;N;;;;; +1939;LIMBU SIGN MUKPHRENG;Mn;222;NSM;;;;;N;;;;; +193A;LIMBU SIGN KEMPHRENG;Mn;230;NSM;;;;;N;;;;; +193B;LIMBU SIGN SA-I;Mn;220;NSM;;;;;N;;;;; +1940;LIMBU SIGN LOO;So;0;ON;;;;;N;;;;; +1944;LIMBU EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +1945;LIMBU QUESTION MARK;Po;0;ON;;;;;N;;;;; +1946;LIMBU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1947;LIMBU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1948;LIMBU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1949;LIMBU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +194A;LIMBU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +194B;LIMBU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +194C;LIMBU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +194D;LIMBU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +194E;LIMBU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +194F;LIMBU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1950;TAI LE LETTER KA;Lo;0;L;;;;;N;;;;; +1951;TAI LE LETTER XA;Lo;0;L;;;;;N;;;;; +1952;TAI LE LETTER NGA;Lo;0;L;;;;;N;;;;; +1953;TAI LE LETTER TSA;Lo;0;L;;;;;N;;;;; +1954;TAI LE LETTER SA;Lo;0;L;;;;;N;;;;; +1955;TAI LE LETTER YA;Lo;0;L;;;;;N;;;;; +1956;TAI LE LETTER TA;Lo;0;L;;;;;N;;;;; +1957;TAI LE LETTER THA;Lo;0;L;;;;;N;;;;; +1958;TAI LE LETTER LA;Lo;0;L;;;;;N;;;;; +1959;TAI LE LETTER PA;Lo;0;L;;;;;N;;;;; +195A;TAI LE LETTER PHA;Lo;0;L;;;;;N;;;;; +195B;TAI LE LETTER MA;Lo;0;L;;;;;N;;;;; +195C;TAI LE LETTER FA;Lo;0;L;;;;;N;;;;; +195D;TAI LE LETTER VA;Lo;0;L;;;;;N;;;;; +195E;TAI LE LETTER HA;Lo;0;L;;;;;N;;;;; +195F;TAI LE LETTER QA;Lo;0;L;;;;;N;;;;; +1960;TAI LE LETTER KHA;Lo;0;L;;;;;N;;;;; +1961;TAI LE LETTER TSHA;Lo;0;L;;;;;N;;;;; +1962;TAI LE LETTER NA;Lo;0;L;;;;;N;;;;; +1963;TAI LE LETTER A;Lo;0;L;;;;;N;;;;; +1964;TAI LE LETTER I;Lo;0;L;;;;;N;;;;; +1965;TAI LE LETTER EE;Lo;0;L;;;;;N;;;;; +1966;TAI LE LETTER EH;Lo;0;L;;;;;N;;;;; +1967;TAI LE LETTER U;Lo;0;L;;;;;N;;;;; +1968;TAI LE LETTER OO;Lo;0;L;;;;;N;;;;; +1969;TAI LE LETTER O;Lo;0;L;;;;;N;;;;; +196A;TAI LE LETTER UE;Lo;0;L;;;;;N;;;;; +196B;TAI LE LETTER E;Lo;0;L;;;;;N;;;;; +196C;TAI LE LETTER AUE;Lo;0;L;;;;;N;;;;; +196D;TAI LE LETTER AI;Lo;0;L;;;;;N;;;;; +1970;TAI LE LETTER TONE-2;Lo;0;L;;;;;N;;;;; +1971;TAI LE LETTER TONE-3;Lo;0;L;;;;;N;;;;; +1972;TAI LE LETTER TONE-4;Lo;0;L;;;;;N;;;;; +1973;TAI LE LETTER TONE-5;Lo;0;L;;;;;N;;;;; +1974;TAI LE LETTER TONE-6;Lo;0;L;;;;;N;;;;; +1980;NEW TAI LUE LETTER HIGH QA;Lo;0;L;;;;;N;;;;; +1981;NEW TAI LUE LETTER LOW QA;Lo;0;L;;;;;N;;;;; +1982;NEW TAI LUE LETTER HIGH KA;Lo;0;L;;;;;N;;;;; +1983;NEW TAI LUE LETTER HIGH XA;Lo;0;L;;;;;N;;;;; +1984;NEW TAI LUE LETTER HIGH NGA;Lo;0;L;;;;;N;;;;; +1985;NEW TAI LUE LETTER LOW KA;Lo;0;L;;;;;N;;;;; +1986;NEW TAI LUE LETTER LOW XA;Lo;0;L;;;;;N;;;;; +1987;NEW TAI LUE LETTER LOW NGA;Lo;0;L;;;;;N;;;;; +1988;NEW TAI LUE LETTER HIGH TSA;Lo;0;L;;;;;N;;;;; +1989;NEW TAI LUE LETTER HIGH SA;Lo;0;L;;;;;N;;;;; +198A;NEW TAI LUE LETTER HIGH YA;Lo;0;L;;;;;N;;;;; +198B;NEW TAI LUE LETTER LOW TSA;Lo;0;L;;;;;N;;;;; +198C;NEW TAI LUE LETTER LOW SA;Lo;0;L;;;;;N;;;;; +198D;NEW TAI LUE LETTER LOW YA;Lo;0;L;;;;;N;;;;; +198E;NEW TAI LUE LETTER HIGH TA;Lo;0;L;;;;;N;;;;; +198F;NEW TAI LUE LETTER HIGH THA;Lo;0;L;;;;;N;;;;; +1990;NEW TAI LUE LETTER HIGH NA;Lo;0;L;;;;;N;;;;; +1991;NEW TAI LUE LETTER LOW TA;Lo;0;L;;;;;N;;;;; +1992;NEW TAI LUE LETTER LOW THA;Lo;0;L;;;;;N;;;;; +1993;NEW TAI LUE LETTER LOW NA;Lo;0;L;;;;;N;;;;; +1994;NEW TAI LUE LETTER HIGH PA;Lo;0;L;;;;;N;;;;; +1995;NEW TAI LUE LETTER HIGH PHA;Lo;0;L;;;;;N;;;;; +1996;NEW TAI LUE LETTER HIGH MA;Lo;0;L;;;;;N;;;;; +1997;NEW TAI LUE LETTER LOW PA;Lo;0;L;;;;;N;;;;; +1998;NEW TAI LUE LETTER LOW PHA;Lo;0;L;;;;;N;;;;; +1999;NEW TAI LUE LETTER LOW MA;Lo;0;L;;;;;N;;;;; +199A;NEW TAI LUE LETTER HIGH FA;Lo;0;L;;;;;N;;;;; +199B;NEW TAI LUE LETTER HIGH VA;Lo;0;L;;;;;N;;;;; +199C;NEW TAI LUE LETTER HIGH LA;Lo;0;L;;;;;N;;;;; +199D;NEW TAI LUE LETTER LOW FA;Lo;0;L;;;;;N;;;;; +199E;NEW TAI LUE LETTER LOW VA;Lo;0;L;;;;;N;;;;; +199F;NEW TAI LUE LETTER LOW LA;Lo;0;L;;;;;N;;;;; +19A0;NEW TAI LUE LETTER HIGH HA;Lo;0;L;;;;;N;;;;; +19A1;NEW TAI LUE LETTER HIGH DA;Lo;0;L;;;;;N;;;;; +19A2;NEW TAI LUE LETTER HIGH BA;Lo;0;L;;;;;N;;;;; +19A3;NEW TAI LUE LETTER LOW HA;Lo;0;L;;;;;N;;;;; +19A4;NEW TAI LUE LETTER LOW DA;Lo;0;L;;;;;N;;;;; +19A5;NEW TAI LUE LETTER LOW BA;Lo;0;L;;;;;N;;;;; +19A6;NEW TAI LUE LETTER HIGH KVA;Lo;0;L;;;;;N;;;;; +19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;; +19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;; +19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;; +19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Mc;0;L;;;;;N;;;;; +19B1;NEW TAI LUE VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +19B2;NEW TAI LUE VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +19B3;NEW TAI LUE VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +19B4;NEW TAI LUE VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +19B5;NEW TAI LUE VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +19B6;NEW TAI LUE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +19B7;NEW TAI LUE VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +19B8;NEW TAI LUE VOWEL SIGN OA;Mc;0;L;;;;;N;;;;; +19B9;NEW TAI LUE VOWEL SIGN UE;Mc;0;L;;;;;N;;;;; +19BA;NEW TAI LUE VOWEL SIGN AY;Mc;0;L;;;;;N;;;;; +19BB;NEW TAI LUE VOWEL SIGN AAY;Mc;0;L;;;;;N;;;;; +19BC;NEW TAI LUE VOWEL SIGN UY;Mc;0;L;;;;;N;;;;; +19BD;NEW TAI LUE VOWEL SIGN OY;Mc;0;L;;;;;N;;;;; +19BE;NEW TAI LUE VOWEL SIGN OAY;Mc;0;L;;;;;N;;;;; +19BF;NEW TAI LUE VOWEL SIGN UEY;Mc;0;L;;;;;N;;;;; +19C0;NEW TAI LUE VOWEL SIGN IY;Mc;0;L;;;;;N;;;;; +19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;; +19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;; +19C4;NEW TAI LUE LETTER FINAL M;Lo;0;L;;;;;N;;;;; +19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;; +19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;; +19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;; +19C8;NEW TAI LUE TONE MARK-1;Mc;0;L;;;;;N;;;;; +19C9;NEW TAI LUE TONE MARK-2;Mc;0;L;;;;;N;;;;; +19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +19D3;NEW TAI LUE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +19D4;NEW TAI LUE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +19D5;NEW TAI LUE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +19D6;NEW TAI LUE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +19DE;NEW TAI LUE SIGN LAE;Po;0;ON;;;;;N;;;;; +19DF;NEW TAI LUE SIGN LAEV;Po;0;ON;;;;;N;;;;; +19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;; +19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;; +19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;; +19E3;KHMER SYMBOL BEI KOET;So;0;ON;;;;;N;;;;; +19E4;KHMER SYMBOL BUON KOET;So;0;ON;;;;;N;;;;; +19E5;KHMER SYMBOL PRAM KOET;So;0;ON;;;;;N;;;;; +19E6;KHMER SYMBOL PRAM-MUOY KOET;So;0;ON;;;;;N;;;;; +19E7;KHMER SYMBOL PRAM-PII KOET;So;0;ON;;;;;N;;;;; +19E8;KHMER SYMBOL PRAM-BEI KOET;So;0;ON;;;;;N;;;;; +19E9;KHMER SYMBOL PRAM-BUON KOET;So;0;ON;;;;;N;;;;; +19EA;KHMER SYMBOL DAP KOET;So;0;ON;;;;;N;;;;; +19EB;KHMER SYMBOL DAP-MUOY KOET;So;0;ON;;;;;N;;;;; +19EC;KHMER SYMBOL DAP-PII KOET;So;0;ON;;;;;N;;;;; +19ED;KHMER SYMBOL DAP-BEI KOET;So;0;ON;;;;;N;;;;; +19EE;KHMER SYMBOL DAP-BUON KOET;So;0;ON;;;;;N;;;;; +19EF;KHMER SYMBOL DAP-PRAM KOET;So;0;ON;;;;;N;;;;; +19F0;KHMER SYMBOL TUTEYASAT;So;0;ON;;;;;N;;;;; +19F1;KHMER SYMBOL MUOY ROC;So;0;ON;;;;;N;;;;; +19F2;KHMER SYMBOL PII ROC;So;0;ON;;;;;N;;;;; +19F3;KHMER SYMBOL BEI ROC;So;0;ON;;;;;N;;;;; +19F4;KHMER SYMBOL BUON ROC;So;0;ON;;;;;N;;;;; +19F5;KHMER SYMBOL PRAM ROC;So;0;ON;;;;;N;;;;; +19F6;KHMER SYMBOL PRAM-MUOY ROC;So;0;ON;;;;;N;;;;; +19F7;KHMER SYMBOL PRAM-PII ROC;So;0;ON;;;;;N;;;;; +19F8;KHMER SYMBOL PRAM-BEI ROC;So;0;ON;;;;;N;;;;; +19F9;KHMER SYMBOL PRAM-BUON ROC;So;0;ON;;;;;N;;;;; +19FA;KHMER SYMBOL DAP ROC;So;0;ON;;;;;N;;;;; +19FB;KHMER SYMBOL DAP-MUOY ROC;So;0;ON;;;;;N;;;;; +19FC;KHMER SYMBOL DAP-PII ROC;So;0;ON;;;;;N;;;;; +19FD;KHMER SYMBOL DAP-BEI ROC;So;0;ON;;;;;N;;;;; +19FE;KHMER SYMBOL DAP-BUON ROC;So;0;ON;;;;;N;;;;; +19FF;KHMER SYMBOL DAP-PRAM ROC;So;0;ON;;;;;N;;;;; +1A00;BUGINESE LETTER KA;Lo;0;L;;;;;N;;;;; +1A01;BUGINESE LETTER GA;Lo;0;L;;;;;N;;;;; +1A02;BUGINESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1A03;BUGINESE LETTER NGKA;Lo;0;L;;;;;N;;;;; +1A04;BUGINESE LETTER PA;Lo;0;L;;;;;N;;;;; +1A05;BUGINESE LETTER BA;Lo;0;L;;;;;N;;;;; +1A06;BUGINESE LETTER MA;Lo;0;L;;;;;N;;;;; +1A07;BUGINESE LETTER MPA;Lo;0;L;;;;;N;;;;; +1A08;BUGINESE LETTER TA;Lo;0;L;;;;;N;;;;; +1A09;BUGINESE LETTER DA;Lo;0;L;;;;;N;;;;; +1A0A;BUGINESE LETTER NA;Lo;0;L;;;;;N;;;;; +1A0B;BUGINESE LETTER NRA;Lo;0;L;;;;;N;;;;; +1A0C;BUGINESE LETTER CA;Lo;0;L;;;;;N;;;;; +1A0D;BUGINESE LETTER JA;Lo;0;L;;;;;N;;;;; +1A0E;BUGINESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1A0F;BUGINESE LETTER NYCA;Lo;0;L;;;;;N;;;;; +1A10;BUGINESE LETTER YA;Lo;0;L;;;;;N;;;;; +1A11;BUGINESE LETTER RA;Lo;0;L;;;;;N;;;;; +1A12;BUGINESE LETTER LA;Lo;0;L;;;;;N;;;;; +1A13;BUGINESE LETTER VA;Lo;0;L;;;;;N;;;;; +1A14;BUGINESE LETTER SA;Lo;0;L;;;;;N;;;;; +1A15;BUGINESE LETTER A;Lo;0;L;;;;;N;;;;; +1A16;BUGINESE LETTER HA;Lo;0;L;;;;;N;;;;; +1A17;BUGINESE VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;; +1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;; +1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1A1B;BUGINESE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;; +1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;; +1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;ardhacandra;;; +1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;candrabindu;;; +1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;anusvara;;; +1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;repha;;; +1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;visarga;;; +1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;a;;; +1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;aa;;; +1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;i;;; +1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;ii;;; +1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;u;;; +1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;uu;;; +1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;vocalic r;;; +1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;vocalic rr;;; +1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;vocalic l;;; +1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;vocalic ll;;; +1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;e;;; +1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;ai;;; +1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;o;;; +1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;au;;; +1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;; +1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;kha;;; +1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;; +1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;gha;;; +1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;; +1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;cha;;; +1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;; +1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;jha;;; +1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;tta;;; +1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;ttha;;; +1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;dda;;; +1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;ddha;;; +1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;nna;;; +1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;; +1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;tha;;; +1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;; +1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;dha;;; +1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;; +1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;; +1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;pha;;; +1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;; +1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;bha;;; +1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;; +1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;; +1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;; +1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;; +1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;; +1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;sha;;; +1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;ssa;;; +1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;; +1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;; +1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;nukta;;; +1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;aa;;; +1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;i;;; +1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;ii;;; +1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;u;;; +1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;uu;;; +1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;vocalic r;;; +1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;vocalic rr;;; +1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;vocalic l;;; +1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;vocalic ll;;; +1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;e;;; +1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;ai;;; +1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;o;;; +1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;au;;; +1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;ae;;; +1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;oe;;; +1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;virama;;; +1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;; +1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;; +1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;; +1B48;BALINESE LETTER EF SASAK;Lo;0;L;;;;;N;;;;; +1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;; +1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;; +1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;; +1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1B53;BALINESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1B54;BALINESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1B55;BALINESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1B56;BALINESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1B5A;BALINESE PANTI;Po;0;L;;;;;N;;section;;; +1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;honorific section;;; +1B5C;BALINESE WINDU;Po;0;L;;;;;N;;punctuation ring;;; +1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;colon;;; +1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;danda;;; +1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;double danda;;; +1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;line-breaking hyphen;;; +1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;; +1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;; +1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;; +1B64;BALINESE MUSICAL SYMBOL DANG;So;0;L;;;;;N;;;;; +1B65;BALINESE MUSICAL SYMBOL DANG SURANG;So;0;L;;;;;N;;;;; +1B66;BALINESE MUSICAL SYMBOL DING;So;0;L;;;;;N;;;;; +1B67;BALINESE MUSICAL SYMBOL DAENG;So;0;L;;;;;N;;;;; +1B68;BALINESE MUSICAL SYMBOL DEUNG;So;0;L;;;;;N;;;;; +1B69;BALINESE MUSICAL SYMBOL DAING;So;0;L;;;;;N;;;;; +1B6A;BALINESE MUSICAL SYMBOL DANG GEDE;So;0;L;;;;;N;;;;; +1B6B;BALINESE MUSICAL SYMBOL COMBINING TEGEH;Mn;230;NSM;;;;;N;;;;; +1B6C;BALINESE MUSICAL SYMBOL COMBINING ENDEP;Mn;220;NSM;;;;;N;;;;; +1B6D;BALINESE MUSICAL SYMBOL COMBINING KEMPUL;Mn;230;NSM;;;;;N;;;;; +1B6E;BALINESE MUSICAL SYMBOL COMBINING KEMPLI;Mn;230;NSM;;;;;N;;;;; +1B6F;BALINESE MUSICAL SYMBOL COMBINING JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B70;BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B71;BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B72;BALINESE MUSICAL SYMBOL COMBINING BENDE;Mn;230;NSM;;;;;N;;;;; +1B73;BALINESE MUSICAL SYMBOL COMBINING GONG;Mn;230;NSM;;;;;N;;;;; +1B74;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG;So;0;L;;;;;N;;;;; +1B75;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG;So;0;L;;;;;N;;;;; +1B76;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK;So;0;L;;;;;N;;;;; +1B77;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK;So;0;L;;;;;N;;;;; +1B78;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG;So;0;L;;;;;N;;;;; +1B79;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG;So;0;L;;;;;N;;;;; +1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;; +1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;; +1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;; +1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;; +1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;; +1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;; +1B83;SUNDANESE LETTER A;Lo;0;L;;;;;N;;;;; +1B84;SUNDANESE LETTER I;Lo;0;L;;;;;N;;;;; +1B85;SUNDANESE LETTER U;Lo;0;L;;;;;N;;;;; +1B86;SUNDANESE LETTER AE;Lo;0;L;;;;;N;;;;; +1B87;SUNDANESE LETTER O;Lo;0;L;;;;;N;;;;; +1B88;SUNDANESE LETTER E;Lo;0;L;;;;;N;;;;; +1B89;SUNDANESE LETTER EU;Lo;0;L;;;;;N;;;;; +1B8A;SUNDANESE LETTER KA;Lo;0;L;;;;;N;;;;; +1B8B;SUNDANESE LETTER QA;Lo;0;L;;;;;N;;;;; +1B8C;SUNDANESE LETTER GA;Lo;0;L;;;;;N;;;;; +1B8D;SUNDANESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1B8E;SUNDANESE LETTER CA;Lo;0;L;;;;;N;;;;; +1B8F;SUNDANESE LETTER JA;Lo;0;L;;;;;N;;;;; +1B90;SUNDANESE LETTER ZA;Lo;0;L;;;;;N;;;;; +1B91;SUNDANESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1B92;SUNDANESE LETTER TA;Lo;0;L;;;;;N;;;;; +1B93;SUNDANESE LETTER DA;Lo;0;L;;;;;N;;;;; +1B94;SUNDANESE LETTER NA;Lo;0;L;;;;;N;;;;; +1B95;SUNDANESE LETTER PA;Lo;0;L;;;;;N;;;;; +1B96;SUNDANESE LETTER FA;Lo;0;L;;;;;N;;;;; +1B97;SUNDANESE LETTER VA;Lo;0;L;;;;;N;;;;; +1B98;SUNDANESE LETTER BA;Lo;0;L;;;;;N;;;;; +1B99;SUNDANESE LETTER MA;Lo;0;L;;;;;N;;;;; +1B9A;SUNDANESE LETTER YA;Lo;0;L;;;;;N;;;;; +1B9B;SUNDANESE LETTER RA;Lo;0;L;;;;;N;;;;; +1B9C;SUNDANESE LETTER LA;Lo;0;L;;;;;N;;;;; +1B9D;SUNDANESE LETTER WA;Lo;0;L;;;;;N;;;;; +1B9E;SUNDANESE LETTER SA;Lo;0;L;;;;;N;;;;; +1B9F;SUNDANESE LETTER XA;Lo;0;L;;;;;N;;;;; +1BA0;SUNDANESE LETTER HA;Lo;0;L;;;;;N;;;;; +1BA1;SUNDANESE CONSONANT SIGN PAMINGKAL;Mc;0;L;;;;;N;;;;; +1BA2;SUNDANESE CONSONANT SIGN PANYAKRA;Mn;0;NSM;;;;;N;;;;; +1BA3;SUNDANESE CONSONANT SIGN PANYIKU;Mn;0;NSM;;;;;N;;;;; +1BA4;SUNDANESE VOWEL SIGN PANGHULU;Mn;0;NSM;;;;;N;;;;; +1BA5;SUNDANESE VOWEL SIGN PANYUKU;Mn;0;NSM;;;;;N;;;;; +1BA6;SUNDANESE VOWEL SIGN PANAELAENG;Mc;0;L;;;;;N;;;;; +1BA7;SUNDANESE VOWEL SIGN PANOLONG;Mc;0;L;;;;;N;;;;; +1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;; +1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;; +1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;; +1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;; +1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;; +1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1BB1;SUNDANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1BB2;SUNDANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1BB3;SUNDANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1BB4;SUNDANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1BB5;SUNDANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1BB6;SUNDANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;; +1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;; +1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;; +1C03;LEPCHA LETTER GA;Lo;0;L;;;;;N;;;;; +1C04;LEPCHA LETTER GLA;Lo;0;L;;;;;N;;;;; +1C05;LEPCHA LETTER NGA;Lo;0;L;;;;;N;;;;; +1C06;LEPCHA LETTER CA;Lo;0;L;;;;;N;;;;; +1C07;LEPCHA LETTER CHA;Lo;0;L;;;;;N;;;;; +1C08;LEPCHA LETTER JA;Lo;0;L;;;;;N;;;;; +1C09;LEPCHA LETTER NYA;Lo;0;L;;;;;N;;;;; +1C0A;LEPCHA LETTER TA;Lo;0;L;;;;;N;;;;; +1C0B;LEPCHA LETTER THA;Lo;0;L;;;;;N;;;;; +1C0C;LEPCHA LETTER DA;Lo;0;L;;;;;N;;;;; +1C0D;LEPCHA LETTER NA;Lo;0;L;;;;;N;;;;; +1C0E;LEPCHA LETTER PA;Lo;0;L;;;;;N;;;;; +1C0F;LEPCHA LETTER PLA;Lo;0;L;;;;;N;;;;; +1C10;LEPCHA LETTER PHA;Lo;0;L;;;;;N;;;;; +1C11;LEPCHA LETTER FA;Lo;0;L;;;;;N;;;;; +1C12;LEPCHA LETTER FLA;Lo;0;L;;;;;N;;;;; +1C13;LEPCHA LETTER BA;Lo;0;L;;;;;N;;;;; +1C14;LEPCHA LETTER BLA;Lo;0;L;;;;;N;;;;; +1C15;LEPCHA LETTER MA;Lo;0;L;;;;;N;;;;; +1C16;LEPCHA LETTER MLA;Lo;0;L;;;;;N;;;;; +1C17;LEPCHA LETTER TSA;Lo;0;L;;;;;N;;;;; +1C18;LEPCHA LETTER TSHA;Lo;0;L;;;;;N;;;;; +1C19;LEPCHA LETTER DZA;Lo;0;L;;;;;N;;;;; +1C1A;LEPCHA LETTER YA;Lo;0;L;;;;;N;;;;; +1C1B;LEPCHA LETTER RA;Lo;0;L;;;;;N;;;;; +1C1C;LEPCHA LETTER LA;Lo;0;L;;;;;N;;;;; +1C1D;LEPCHA LETTER HA;Lo;0;L;;;;;N;;;;; +1C1E;LEPCHA LETTER HLA;Lo;0;L;;;;;N;;;;; +1C1F;LEPCHA LETTER VA;Lo;0;L;;;;;N;;;;; +1C20;LEPCHA LETTER SA;Lo;0;L;;;;;N;;;;; +1C21;LEPCHA LETTER SHA;Lo;0;L;;;;;N;;;;; +1C22;LEPCHA LETTER WA;Lo;0;L;;;;;N;;;;; +1C23;LEPCHA LETTER A;Lo;0;L;;;;;N;;;;; +1C24;LEPCHA SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;; +1C25;LEPCHA SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;; +1C26;LEPCHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1C27;LEPCHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +1C28;LEPCHA VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1C29;LEPCHA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1C2A;LEPCHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +1C2B;LEPCHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +1C2C;LEPCHA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1C2D;LEPCHA CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;; +1C2E;LEPCHA CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;; +1C2F;LEPCHA CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;; +1C30;LEPCHA CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +1C31;LEPCHA CONSONANT SIGN P;Mn;0;NSM;;;;;N;;;;; +1C32;LEPCHA CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +1C33;LEPCHA CONSONANT SIGN T;Mn;0;NSM;;;;;N;;;;; +1C34;LEPCHA CONSONANT SIGN NYIN-DO;Mc;0;L;;;;;N;;;;; +1C35;LEPCHA CONSONANT SIGN KANG;Mc;0;L;;;;;N;;;;; +1C36;LEPCHA SIGN RAN;Mn;0;NSM;;;;;N;;;;; +1C37;LEPCHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +1C3B;LEPCHA PUNCTUATION TA-ROL;Po;0;L;;;;;N;;;;; +1C3C;LEPCHA PUNCTUATION NYET THYOOM TA-ROL;Po;0;L;;;;;N;;;;; +1C3D;LEPCHA PUNCTUATION CER-WA;Po;0;L;;;;;N;;;;; +1C3E;LEPCHA PUNCTUATION TSHOOK CER-WA;Po;0;L;;;;;N;;;;; +1C3F;LEPCHA PUNCTUATION TSHOOK;Po;0;L;;;;;N;;;;; +1C40;LEPCHA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1C41;LEPCHA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1C42;LEPCHA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1C43;LEPCHA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1C44;LEPCHA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1C45;LEPCHA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1C46;LEPCHA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1C47;LEPCHA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1C48;LEPCHA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1C49;LEPCHA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C4D;LEPCHA LETTER TTA;Lo;0;L;;;;;N;;;;; +1C4E;LEPCHA LETTER TTHA;Lo;0;L;;;;;N;;;;; +1C4F;LEPCHA LETTER DDA;Lo;0;L;;;;;N;;;;; +1C50;OL CHIKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1C51;OL CHIKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1C52;OL CHIKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1C53;OL CHIKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1C54;OL CHIKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1C55;OL CHIKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1C56;OL CHIKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1C57;OL CHIKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1C58;OL CHIKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1C59;OL CHIKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C5A;OL CHIKI LETTER LA;Lo;0;L;;;;;N;;;;; +1C5B;OL CHIKI LETTER AT;Lo;0;L;;;;;N;;;;; +1C5C;OL CHIKI LETTER AG;Lo;0;L;;;;;N;;;;; +1C5D;OL CHIKI LETTER ANG;Lo;0;L;;;;;N;;;;; +1C5E;OL CHIKI LETTER AL;Lo;0;L;;;;;N;;;;; +1C5F;OL CHIKI LETTER LAA;Lo;0;L;;;;;N;;;;; +1C60;OL CHIKI LETTER AAK;Lo;0;L;;;;;N;;;;; +1C61;OL CHIKI LETTER AAJ;Lo;0;L;;;;;N;;;;; +1C62;OL CHIKI LETTER AAM;Lo;0;L;;;;;N;;;;; +1C63;OL CHIKI LETTER AAW;Lo;0;L;;;;;N;;;;; +1C64;OL CHIKI LETTER LI;Lo;0;L;;;;;N;;;;; +1C65;OL CHIKI LETTER IS;Lo;0;L;;;;;N;;;;; +1C66;OL CHIKI LETTER IH;Lo;0;L;;;;;N;;;;; +1C67;OL CHIKI LETTER INY;Lo;0;L;;;;;N;;;;; +1C68;OL CHIKI LETTER IR;Lo;0;L;;;;;N;;;;; +1C69;OL CHIKI LETTER LU;Lo;0;L;;;;;N;;;;; +1C6A;OL CHIKI LETTER UC;Lo;0;L;;;;;N;;;;; +1C6B;OL CHIKI LETTER UD;Lo;0;L;;;;;N;;;;; +1C6C;OL CHIKI LETTER UNN;Lo;0;L;;;;;N;;;;; +1C6D;OL CHIKI LETTER UY;Lo;0;L;;;;;N;;;;; +1C6E;OL CHIKI LETTER LE;Lo;0;L;;;;;N;;;;; +1C6F;OL CHIKI LETTER EP;Lo;0;L;;;;;N;;;;; +1C70;OL CHIKI LETTER EDD;Lo;0;L;;;;;N;;;;; +1C71;OL CHIKI LETTER EN;Lo;0;L;;;;;N;;;;; +1C72;OL CHIKI LETTER ERR;Lo;0;L;;;;;N;;;;; +1C73;OL CHIKI LETTER LO;Lo;0;L;;;;;N;;;;; +1C74;OL CHIKI LETTER OTT;Lo;0;L;;;;;N;;;;; +1C75;OL CHIKI LETTER OB;Lo;0;L;;;;;N;;;;; +1C76;OL CHIKI LETTER OV;Lo;0;L;;;;;N;;;;; +1C77;OL CHIKI LETTER OH;Lo;0;L;;;;;N;;;;; +1C78;OL CHIKI MU TTUDDAG;Lm;0;L;;;;;N;;;;; +1C79;OL CHIKI GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;; +1C7A;OL CHIKI MU-GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;; +1C7B;OL CHIKI RELAA;Lm;0;L;;;;;N;;;;; +1C7C;OL CHIKI PHAARKAA;Lm;0;L;;;;;N;;;;; +1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;; +1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;; +1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;; +1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;; +1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;; +1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;; +1D03;LATIN LETTER SMALL CAPITAL BARRED B;Ll;0;L;;;;;N;;;;; +1D04;LATIN LETTER SMALL CAPITAL C;Ll;0;L;;;;;N;;;;; +1D05;LATIN LETTER SMALL CAPITAL D;Ll;0;L;;;;;N;;;;; +1D06;LATIN LETTER SMALL CAPITAL ETH;Ll;0;L;;;;;N;;;;; +1D07;LATIN LETTER SMALL CAPITAL E;Ll;0;L;;;;;N;;;;; +1D08;LATIN SMALL LETTER TURNED OPEN E;Ll;0;L;;;;;N;;;;; +1D09;LATIN SMALL LETTER TURNED I;Ll;0;L;;;;;N;;;;; +1D0A;LATIN LETTER SMALL CAPITAL J;Ll;0;L;;;;;N;;;;; +1D0B;LATIN LETTER SMALL CAPITAL K;Ll;0;L;;;;;N;;;;; +1D0C;LATIN LETTER SMALL CAPITAL L WITH STROKE;Ll;0;L;;;;;N;;;;; +1D0D;LATIN LETTER SMALL CAPITAL M;Ll;0;L;;;;;N;;;;; +1D0E;LATIN LETTER SMALL CAPITAL REVERSED N;Ll;0;L;;;;;N;;;;; +1D0F;LATIN LETTER SMALL CAPITAL O;Ll;0;L;;;;;N;;;;; +1D10;LATIN LETTER SMALL CAPITAL OPEN O;Ll;0;L;;;;;N;;;;; +1D11;LATIN SMALL LETTER SIDEWAYS O;Ll;0;L;;;;;N;;;;; +1D12;LATIN SMALL LETTER SIDEWAYS OPEN O;Ll;0;L;;;;;N;;;;; +1D13;LATIN SMALL LETTER SIDEWAYS O WITH STROKE;Ll;0;L;;;;;N;;;;; +1D14;LATIN SMALL LETTER TURNED OE;Ll;0;L;;;;;N;;;;; +1D15;LATIN LETTER SMALL CAPITAL OU;Ll;0;L;;;;;N;;;;; +1D16;LATIN SMALL LETTER TOP HALF O;Ll;0;L;;;;;N;;;;; +1D17;LATIN SMALL LETTER BOTTOM HALF O;Ll;0;L;;;;;N;;;;; +1D18;LATIN LETTER SMALL CAPITAL P;Ll;0;L;;;;;N;;;;; +1D19;LATIN LETTER SMALL CAPITAL REVERSED R;Ll;0;L;;;;;N;;;;; +1D1A;LATIN LETTER SMALL CAPITAL TURNED R;Ll;0;L;;;;;N;;;;; +1D1B;LATIN LETTER SMALL CAPITAL T;Ll;0;L;;;;;N;;;;; +1D1C;LATIN LETTER SMALL CAPITAL U;Ll;0;L;;;;;N;;;;; +1D1D;LATIN SMALL LETTER SIDEWAYS U;Ll;0;L;;;;;N;;;;; +1D1E;LATIN SMALL LETTER SIDEWAYS DIAERESIZED U;Ll;0;L;;;;;N;;;;; +1D1F;LATIN SMALL LETTER SIDEWAYS TURNED M;Ll;0;L;;;;;N;;;;; +1D20;LATIN LETTER SMALL CAPITAL V;Ll;0;L;;;;;N;;;;; +1D21;LATIN LETTER SMALL CAPITAL W;Ll;0;L;;;;;N;;;;; +1D22;LATIN LETTER SMALL CAPITAL Z;Ll;0;L;;;;;N;;;;; +1D23;LATIN LETTER SMALL CAPITAL EZH;Ll;0;L;;;;;N;;;;; +1D24;LATIN LETTER VOICED LARYNGEAL SPIRANT;Ll;0;L;;;;;N;;;;; +1D25;LATIN LETTER AIN;Ll;0;L;;;;;N;;;;; +1D26;GREEK LETTER SMALL CAPITAL GAMMA;Ll;0;L;;;;;N;;;;; +1D27;GREEK LETTER SMALL CAPITAL LAMDA;Ll;0;L;;;;;N;;;;; +1D28;GREEK LETTER SMALL CAPITAL PI;Ll;0;L;;;;;N;;;;; +1D29;GREEK LETTER SMALL CAPITAL RHO;Ll;0;L;;;;;N;;;;; +1D2A;GREEK LETTER SMALL CAPITAL PSI;Ll;0;L;;;;;N;;;;; +1D2B;CYRILLIC LETTER SMALL CAPITAL EL;Ll;0;L;;;;;N;;;;; +1D2C;MODIFIER LETTER CAPITAL A;Lm;0;L; 0041;;;;N;;;;; +1D2D;MODIFIER LETTER CAPITAL AE;Lm;0;L; 00C6;;;;N;;;;; +1D2E;MODIFIER LETTER CAPITAL B;Lm;0;L; 0042;;;;N;;;;; +1D2F;MODIFIER LETTER CAPITAL BARRED B;Lm;0;L;;;;;N;;;;; +1D30;MODIFIER LETTER CAPITAL D;Lm;0;L; 0044;;;;N;;;;; +1D31;MODIFIER LETTER CAPITAL E;Lm;0;L; 0045;;;;N;;;;; +1D32;MODIFIER LETTER CAPITAL REVERSED E;Lm;0;L; 018E;;;;N;;;;; +1D33;MODIFIER LETTER CAPITAL G;Lm;0;L; 0047;;;;N;;;;; +1D34;MODIFIER LETTER CAPITAL H;Lm;0;L; 0048;;;;N;;;;; +1D35;MODIFIER LETTER CAPITAL I;Lm;0;L; 0049;;;;N;;;;; +1D36;MODIFIER LETTER CAPITAL J;Lm;0;L; 004A;;;;N;;;;; +1D37;MODIFIER LETTER CAPITAL K;Lm;0;L; 004B;;;;N;;;;; +1D38;MODIFIER LETTER CAPITAL L;Lm;0;L; 004C;;;;N;;;;; +1D39;MODIFIER LETTER CAPITAL M;Lm;0;L; 004D;;;;N;;;;; +1D3A;MODIFIER LETTER CAPITAL N;Lm;0;L; 004E;;;;N;;;;; +1D3B;MODIFIER LETTER CAPITAL REVERSED N;Lm;0;L;;;;;N;;;;; +1D3C;MODIFIER LETTER CAPITAL O;Lm;0;L; 004F;;;;N;;;;; +1D3D;MODIFIER LETTER CAPITAL OU;Lm;0;L; 0222;;;;N;;;;; +1D3E;MODIFIER LETTER CAPITAL P;Lm;0;L; 0050;;;;N;;;;; +1D3F;MODIFIER LETTER CAPITAL R;Lm;0;L; 0052;;;;N;;;;; +1D40;MODIFIER LETTER CAPITAL T;Lm;0;L; 0054;;;;N;;;;; +1D41;MODIFIER LETTER CAPITAL U;Lm;0;L; 0055;;;;N;;;;; +1D42;MODIFIER LETTER CAPITAL W;Lm;0;L; 0057;;;;N;;;;; +1D43;MODIFIER LETTER SMALL A;Lm;0;L; 0061;;;;N;;;;; +1D44;MODIFIER LETTER SMALL TURNED A;Lm;0;L; 0250;;;;N;;;;; +1D45;MODIFIER LETTER SMALL ALPHA;Lm;0;L; 0251;;;;N;;;;; +1D46;MODIFIER LETTER SMALL TURNED AE;Lm;0;L; 1D02;;;;N;;;;; +1D47;MODIFIER LETTER SMALL B;Lm;0;L; 0062;;;;N;;;;; +1D48;MODIFIER LETTER SMALL D;Lm;0;L; 0064;;;;N;;;;; +1D49;MODIFIER LETTER SMALL E;Lm;0;L; 0065;;;;N;;;;; +1D4A;MODIFIER LETTER SMALL SCHWA;Lm;0;L; 0259;;;;N;;;;; +1D4B;MODIFIER LETTER SMALL OPEN E;Lm;0;L; 025B;;;;N;;;;; +1D4C;MODIFIER LETTER SMALL TURNED OPEN E;Lm;0;L; 025C;;;;N;;;;; +1D4D;MODIFIER LETTER SMALL G;Lm;0;L; 0067;;;;N;;;;; +1D4E;MODIFIER LETTER SMALL TURNED I;Lm;0;L;;;;;N;;;;; +1D4F;MODIFIER LETTER SMALL K;Lm;0;L; 006B;;;;N;;;;; +1D50;MODIFIER LETTER SMALL M;Lm;0;L; 006D;;;;N;;;;; +1D51;MODIFIER LETTER SMALL ENG;Lm;0;L; 014B;;;;N;;;;; +1D52;MODIFIER LETTER SMALL O;Lm;0;L; 006F;;;;N;;;;; +1D53;MODIFIER LETTER SMALL OPEN O;Lm;0;L; 0254;;;;N;;;;; +1D54;MODIFIER LETTER SMALL TOP HALF O;Lm;0;L; 1D16;;;;N;;;;; +1D55;MODIFIER LETTER SMALL BOTTOM HALF O;Lm;0;L; 1D17;;;;N;;;;; +1D56;MODIFIER LETTER SMALL P;Lm;0;L; 0070;;;;N;;;;; +1D57;MODIFIER LETTER SMALL T;Lm;0;L; 0074;;;;N;;;;; +1D58;MODIFIER LETTER SMALL U;Lm;0;L; 0075;;;;N;;;;; +1D59;MODIFIER LETTER SMALL SIDEWAYS U;Lm;0;L; 1D1D;;;;N;;;;; +1D5A;MODIFIER LETTER SMALL TURNED M;Lm;0;L; 026F;;;;N;;;;; +1D5B;MODIFIER LETTER SMALL V;Lm;0;L; 0076;;;;N;;;;; +1D5C;MODIFIER LETTER SMALL AIN;Lm;0;L; 1D25;;;;N;;;;; +1D5D;MODIFIER LETTER SMALL BETA;Lm;0;L; 03B2;;;;N;;;;; +1D5E;MODIFIER LETTER SMALL GREEK GAMMA;Lm;0;L; 03B3;;;;N;;;;; +1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L; 03B4;;;;N;;;;; +1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L; 03C6;;;;N;;;;; +1D61;MODIFIER LETTER SMALL CHI;Lm;0;L; 03C7;;;;N;;;;; +1D62;LATIN SUBSCRIPT SMALL LETTER I;Ll;0;L; 0069;;;;N;;;;; +1D63;LATIN SUBSCRIPT SMALL LETTER R;Ll;0;L; 0072;;;;N;;;;; +1D64;LATIN SUBSCRIPT SMALL LETTER U;Ll;0;L; 0075;;;;N;;;;; +1D65;LATIN SUBSCRIPT SMALL LETTER V;Ll;0;L; 0076;;;;N;;;;; +1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Ll;0;L; 03B2;;;;N;;;;; +1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Ll;0;L; 03C1;;;;N;;;;; +1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Ll;0;L; 03C6;;;;N;;;;; +1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Ll;0;L; 03C7;;;;N;;;;; +1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;; +1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6E;LATIN SMALL LETTER F WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6F;LATIN SMALL LETTER M WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D70;LATIN SMALL LETTER N WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D71;LATIN SMALL LETTER P WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D72;LATIN SMALL LETTER R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D73;LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D74;LATIN SMALL LETTER S WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D75;LATIN SMALL LETTER T WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D76;LATIN SMALL LETTER Z WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D77;LATIN SMALL LETTER TURNED G;Ll;0;L;;;;;N;;;;; +1D78;MODIFIER LETTER CYRILLIC EN;Lm;0;L; 043D;;;;N;;;;; +1D79;LATIN SMALL LETTER INSULAR G;Ll;0;L;;;;;N;;;A77D;;A77D +1D7A;LATIN SMALL LETTER TH WITH STRIKETHROUGH;Ll;0;L;;;;;N;;;;; +1D7B;LATIN SMALL CAPITAL LETTER I WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7C;LATIN SMALL LETTER IOTA WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7D;LATIN SMALL LETTER P WITH STROKE;Ll;0;L;;;;;N;;;2C63;;2C63 +1D7E;LATIN SMALL CAPITAL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7F;LATIN SMALL LETTER UPSILON WITH STROKE;Ll;0;L;;;;;N;;;;; +1D80;LATIN SMALL LETTER B WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D81;LATIN SMALL LETTER D WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D82;LATIN SMALL LETTER F WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D83;LATIN SMALL LETTER G WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D84;LATIN SMALL LETTER K WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D85;LATIN SMALL LETTER L WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D86;LATIN SMALL LETTER M WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D87;LATIN SMALL LETTER N WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D88;LATIN SMALL LETTER P WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D89;LATIN SMALL LETTER R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8A;LATIN SMALL LETTER S WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;; +1D92;LATIN SMALL LETTER E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D93;LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D94;LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D95;LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D96;LATIN SMALL LETTER I WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D97;LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D98;LATIN SMALL LETTER ESH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D99;LATIN SMALL LETTER U WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D9A;LATIN SMALL LETTER EZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D9B;MODIFIER LETTER SMALL TURNED ALPHA;Lm;0;L; 0252;;;;N;;;;; +1D9C;MODIFIER LETTER SMALL C;Lm;0;L; 0063;;;;N;;;;; +1D9D;MODIFIER LETTER SMALL C WITH CURL;Lm;0;L; 0255;;;;N;;;;; +1D9E;MODIFIER LETTER SMALL ETH;Lm;0;L; 00F0;;;;N;;;;; +1D9F;MODIFIER LETTER SMALL REVERSED OPEN E;Lm;0;L; 025C;;;;N;;;;; +1DA0;MODIFIER LETTER SMALL F;Lm;0;L; 0066;;;;N;;;;; +1DA1;MODIFIER LETTER SMALL DOTLESS J WITH STROKE;Lm;0;L; 025F;;;;N;;;;; +1DA2;MODIFIER LETTER SMALL SCRIPT G;Lm;0;L; 0261;;;;N;;;;; +1DA3;MODIFIER LETTER SMALL TURNED H;Lm;0;L; 0265;;;;N;;;;; +1DA4;MODIFIER LETTER SMALL I WITH STROKE;Lm;0;L; 0268;;;;N;;;;; +1DA5;MODIFIER LETTER SMALL IOTA;Lm;0;L; 0269;;;;N;;;;; +1DA6;MODIFIER LETTER SMALL CAPITAL I;Lm;0;L; 026A;;;;N;;;;; +1DA7;MODIFIER LETTER SMALL CAPITAL I WITH STROKE;Lm;0;L; 1D7B;;;;N;;;;; +1DA8;MODIFIER LETTER SMALL J WITH CROSSED-TAIL;Lm;0;L; 029D;;;;N;;;;; +1DA9;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK;Lm;0;L; 026D;;;;N;;;;; +1DAA;MODIFIER LETTER SMALL L WITH PALATAL HOOK;Lm;0;L; 1D85;;;;N;;;;; +1DAB;MODIFIER LETTER SMALL CAPITAL L;Lm;0;L; 029F;;;;N;;;;; +1DAC;MODIFIER LETTER SMALL M WITH HOOK;Lm;0;L; 0271;;;;N;;;;; +1DAD;MODIFIER LETTER SMALL TURNED M WITH LONG LEG;Lm;0;L; 0270;;;;N;;;;; +1DAE;MODIFIER LETTER SMALL N WITH LEFT HOOK;Lm;0;L; 0272;;;;N;;;;; +1DAF;MODIFIER LETTER SMALL N WITH RETROFLEX HOOK;Lm;0;L; 0273;;;;N;;;;; +1DB0;MODIFIER LETTER SMALL CAPITAL N;Lm;0;L; 0274;;;;N;;;;; +1DB1;MODIFIER LETTER SMALL BARRED O;Lm;0;L; 0275;;;;N;;;;; +1DB2;MODIFIER LETTER SMALL PHI;Lm;0;L; 0278;;;;N;;;;; +1DB3;MODIFIER LETTER SMALL S WITH HOOK;Lm;0;L; 0282;;;;N;;;;; +1DB4;MODIFIER LETTER SMALL ESH;Lm;0;L; 0283;;;;N;;;;; +1DB5;MODIFIER LETTER SMALL T WITH PALATAL HOOK;Lm;0;L; 01AB;;;;N;;;;; +1DB6;MODIFIER LETTER SMALL U BAR;Lm;0;L; 0289;;;;N;;;;; +1DB7;MODIFIER LETTER SMALL UPSILON;Lm;0;L; 028A;;;;N;;;;; +1DB8;MODIFIER LETTER SMALL CAPITAL U;Lm;0;L; 1D1C;;;;N;;;;; +1DB9;MODIFIER LETTER SMALL V WITH HOOK;Lm;0;L; 028B;;;;N;;;;; +1DBA;MODIFIER LETTER SMALL TURNED V;Lm;0;L; 028C;;;;N;;;;; +1DBB;MODIFIER LETTER SMALL Z;Lm;0;L; 007A;;;;N;;;;; +1DBC;MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK;Lm;0;L; 0290;;;;N;;;;; +1DBD;MODIFIER LETTER SMALL Z WITH CURL;Lm;0;L; 0291;;;;N;;;;; +1DBE;MODIFIER LETTER SMALL EZH;Lm;0;L; 0292;;;;N;;;;; +1DBF;MODIFIER LETTER SMALL THETA;Lm;0;L; 03B8;;;;N;;;;; +1DC0;COMBINING DOTTED GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; +1DC1;COMBINING DOTTED ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +1DC2;COMBINING SNAKE BELOW;Mn;220;NSM;;;;;N;;;;; +1DC3;COMBINING SUSPENSION MARK;Mn;230;NSM;;;;;N;;;;; +1DC4;COMBINING MACRON-ACUTE;Mn;230;NSM;;;;;N;;;;; +1DC5;COMBINING GRAVE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DC6;COMBINING MACRON-GRAVE;Mn;230;NSM;;;;;N;;;;; +1DC7;COMBINING ACUTE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DC8;COMBINING GRAVE-ACUTE-GRAVE;Mn;230;NSM;;;;;N;;;;; +1DC9;COMBINING ACUTE-GRAVE-ACUTE;Mn;230;NSM;;;;;N;;;;; +1DCA;COMBINING LATIN SMALL LETTER R BELOW;Mn;220;NSM;;;;;N;;;;; +1DCB;COMBINING BREVE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DCC;COMBINING MACRON-BREVE;Mn;230;NSM;;;;;N;;;;; +1DCD;COMBINING DOUBLE CIRCUMFLEX ABOVE;Mn;234;NSM;;;;;N;;;;; +1DCE;COMBINING OGONEK ABOVE;Mn;214;NSM;;;;;N;;;;; +1DCF;COMBINING ZIGZAG BELOW;Mn;220;NSM;;;;;N;;;;; +1DD0;COMBINING IS BELOW;Mn;202;NSM;;;;;N;;;;; +1DD1;COMBINING UR ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD2;COMBINING US ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD3;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD4;COMBINING LATIN SMALL LETTER AE;Mn;230;NSM;;;;;N;;;;; +1DD5;COMBINING LATIN SMALL LETTER AO;Mn;230;NSM;;;;;N;;;;; +1DD6;COMBINING LATIN SMALL LETTER AV;Mn;230;NSM;;;;;N;;;;; +1DD7;COMBINING LATIN SMALL LETTER C CEDILLA;Mn;230;NSM;;;;;N;;;;; +1DD8;COMBINING LATIN SMALL LETTER INSULAR D;Mn;230;NSM;;;;;N;;;;; +1DD9;COMBINING LATIN SMALL LETTER ETH;Mn;230;NSM;;;;;N;;;;; +1DDA;COMBINING LATIN SMALL LETTER G;Mn;230;NSM;;;;;N;;;;; +1DDB;COMBINING LATIN LETTER SMALL CAPITAL G;Mn;230;NSM;;;;;N;;;;; +1DDC;COMBINING LATIN SMALL LETTER K;Mn;230;NSM;;;;;N;;;;; +1DDD;COMBINING LATIN SMALL LETTER L;Mn;230;NSM;;;;;N;;;;; +1DDE;COMBINING LATIN LETTER SMALL CAPITAL L;Mn;230;NSM;;;;;N;;;;; +1DDF;COMBINING LATIN LETTER SMALL CAPITAL M;Mn;230;NSM;;;;;N;;;;; +1DE0;COMBINING LATIN SMALL LETTER N;Mn;230;NSM;;;;;N;;;;; +1DE1;COMBINING LATIN LETTER SMALL CAPITAL N;Mn;230;NSM;;;;;N;;;;; +1DE2;COMBINING LATIN LETTER SMALL CAPITAL R;Mn;230;NSM;;;;;N;;;;; +1DE3;COMBINING LATIN SMALL LETTER R ROTUNDA;Mn;230;NSM;;;;;N;;;;; +1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;; +1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;; +1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;; +1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01; +1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00 +1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03; +1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02 +1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05; +1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04 +1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07; +1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06 +1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09; +1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08 +1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B; +1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A +1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D; +1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C +1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F; +1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E +1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11; +1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10 +1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13; +1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12 +1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15; +1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14 +1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17; +1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16 +1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19; +1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18 +1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B; +1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A +1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D; +1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C +1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F; +1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E +1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21; +1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20 +1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23; +1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22 +1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25; +1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24 +1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27; +1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26 +1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29; +1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28 +1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B; +1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A +1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D; +1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C +1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F; +1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E +1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31; +1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30 +1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33; +1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32 +1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35; +1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34 +1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37; +1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36 +1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39; +1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38 +1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B; +1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A +1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D; +1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C +1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F; +1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E +1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41; +1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40 +1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43; +1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42 +1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45; +1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44 +1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47; +1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46 +1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49; +1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48 +1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B; +1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A +1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D; +1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C +1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F; +1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E +1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51; +1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50 +1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53; +1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52 +1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55; +1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54 +1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57; +1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56 +1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59; +1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58 +1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B; +1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A +1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D; +1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C +1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F; +1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E +1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61; +1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60 +1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63; +1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62 +1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65; +1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64 +1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67; +1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66 +1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69; +1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68 +1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B; +1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A +1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D; +1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C +1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F; +1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E +1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71; +1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70 +1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73; +1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72 +1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75; +1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74 +1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77; +1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76 +1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79; +1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78 +1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B; +1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A +1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D; +1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C +1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F; +1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E +1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81; +1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80 +1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83; +1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82 +1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85; +1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84 +1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87; +1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86 +1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89; +1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88 +1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B; +1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A +1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D; +1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C +1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F; +1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E +1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91; +1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90 +1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93; +1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92 +1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95; +1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94 +1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;; +1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;; +1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;; +1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;; +1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L; 0061 02BE;;;;N;;;;; +1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60 +1E9C;LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;;; +1E9D;LATIN SMALL LETTER LONG S WITH HIGH STROKE;Ll;0;L;;;;;N;;;;; +1E9E;LATIN CAPITAL LETTER SHARP S;Lu;0;L;;;;;N;;;;00DF; +1E9F;LATIN SMALL LETTER DELTA;Ll;0;L;;;;;N;;;;; +1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1; +1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0 +1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3; +1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2 +1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5; +1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4 +1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7; +1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6 +1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9; +1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8 +1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB; +1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA +1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD; +1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC +1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF; +1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE +1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1; +1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0 +1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3; +1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2 +1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5; +1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4 +1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7; +1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6 +1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9; +1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8 +1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB; +1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA +1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD; +1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC +1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF; +1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE +1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1; +1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0 +1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3; +1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2 +1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5; +1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4 +1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7; +1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6 +1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9; +1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8 +1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB; +1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA +1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD; +1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC +1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF; +1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE +1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1; +1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0 +1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3; +1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2 +1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5; +1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4 +1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7; +1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6 +1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9; +1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8 +1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB; +1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA +1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD; +1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC +1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF; +1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE +1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1; +1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0 +1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3; +1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2 +1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5; +1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4 +1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7; +1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6 +1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9; +1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8 +1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB; +1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA +1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED; +1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC +1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF; +1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE +1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1; +1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0 +1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3; +1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2 +1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5; +1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4 +1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7; +1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6 +1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9; +1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8 +1EFA;LATIN CAPITAL LETTER MIDDLE-WELSH LL;Lu;0;L;;;;;N;;;;1EFB; +1EFB;LATIN SMALL LETTER MIDDLE-WELSH LL;Ll;0;L;;;;;N;;;1EFA;;1EFA +1EFC;LATIN CAPITAL LETTER MIDDLE-WELSH V;Lu;0;L;;;;;N;;;;1EFD; +1EFD;LATIN SMALL LETTER MIDDLE-WELSH V;Ll;0;L;;;;;N;;;1EFC;;1EFC +1EFE;LATIN CAPITAL LETTER Y WITH LOOP;Lu;0;L;;;;;N;;;;1EFF; +1EFF;LATIN SMALL LETTER Y WITH LOOP;Ll;0;L;;;;;N;;;1EFE;;1EFE +1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08 +1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09 +1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A +1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B +1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C +1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D +1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E +1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F +1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00; +1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01; +1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02; +1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03; +1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04; +1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05; +1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06; +1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07; +1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18 +1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19 +1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A +1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B +1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C +1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D +1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10; +1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11; +1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12; +1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13; +1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14; +1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15; +1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28 +1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29 +1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A +1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B +1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C +1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D +1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E +1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F +1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20; +1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21; +1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22; +1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23; +1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24; +1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25; +1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26; +1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27; +1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38 +1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39 +1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A +1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B +1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C +1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D +1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E +1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F +1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30; +1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31; +1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32; +1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33; +1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34; +1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35; +1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36; +1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37; +1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48 +1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49 +1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A +1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B +1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C +1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D +1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40; +1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41; +1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42; +1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43; +1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44; +1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45; +1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;; +1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59 +1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;; +1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B +1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;; +1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D +1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;; +1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F +1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51; +1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53; +1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55; +1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57; +1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68 +1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69 +1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A +1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B +1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C +1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D +1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E +1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F +1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60; +1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61; +1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62; +1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63; +1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64; +1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65; +1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66; +1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67; +1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA +1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB +1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8 +1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9 +1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA +1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB +1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA +1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB +1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8 +1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9 +1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA +1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB +1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA +1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB +1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88 +1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89 +1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A +1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B +1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C +1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D +1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E +1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F +1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80; +1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81; +1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82; +1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83; +1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84; +1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85; +1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86; +1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87; +1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98 +1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99 +1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A +1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B +1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C +1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D +1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E +1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F +1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90; +1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91; +1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92; +1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93; +1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94; +1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95; +1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96; +1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97; +1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8 +1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9 +1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA +1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB +1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC +1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD +1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE +1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF +1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0; +1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1; +1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2; +1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3; +1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4; +1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5; +1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6; +1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7; +1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8 +1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9 +1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;; +1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC +1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;; +1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;; +1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;; +1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0; +1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1; +1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70; +1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71; +1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3; +1FBD;GREEK KORONIS;Sk;0;ON; 0020 0313;;;;N;;;;; +1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399 +1FBF;GREEK PSILI;Sk;0;ON; 0020 0313;;;;N;;;;; +1FC0;GREEK PERISPOMENI;Sk;0;ON; 0020 0342;;;;N;;;;; +1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;; +1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;; +1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC +1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;; +1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;; +1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;; +1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72; +1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73; +1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74; +1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75; +1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3; +1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;; +1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;; +1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;; +1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8 +1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9 +1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;; +1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;; +1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;; +1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;; +1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0; +1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1; +1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76; +1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77; +1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;; +1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;; +1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;; +1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8 +1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9 +1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;; +1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;; +1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;; +1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC +1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;; +1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;; +1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0; +1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1; +1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A; +1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B; +1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5; +1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;; +1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;; +1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;; +1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;; +1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC +1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;; +1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;; +1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;; +1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78; +1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79; +1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C; +1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D; +1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3; +1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;; +1FFE;GREEK DASIA;Sk;0;ON; 0020 0314;;;;N;;;;; +2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;; +2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;; +2002;EN SPACE;Zs;0;WS; 0020;;;;N;;;;; +2003;EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2004;THREE-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2005;FOUR-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2006;SIX-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2007;FIGURE SPACE;Zs;0;WS; 0020;;;;N;;;;; +2008;PUNCTUATION SPACE;Zs;0;WS; 0020;;;;N;;;;; +2009;THIN SPACE;Zs;0;WS; 0020;;;;N;;;;; +200A;HAIR SPACE;Zs;0;WS; 0020;;;;N;;;;; +200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;; +200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;; +200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;; +200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;; +200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;; +2010;HYPHEN;Pd;0;ON;;;;;N;;;;; +2011;NON-BREAKING HYPHEN;Pd;0;ON; 2010;;;;N;;;;; +2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;; +2013;EN DASH;Pd;0;ON;;;;;N;;;;; +2014;EM DASH;Pd;0;ON;;;;;N;;;;; +2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;; +2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;; +2017;DOUBLE LOW LINE;Po;0;ON; 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;; +2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;; +2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;; +201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;; +201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;; +201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;; +201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;; +201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;; +201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;; +2020;DAGGER;Po;0;ON;;;;;N;;;;; +2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;; +2022;BULLET;Po;0;ON;;;;;N;;;;; +2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;; +2024;ONE DOT LEADER;Po;0;ON; 002E;;;;N;;;;; +2025;TWO DOT LEADER;Po;0;ON; 002E 002E;;;;N;;;;; +2026;HORIZONTAL ELLIPSIS;Po;0;ON; 002E 002E 002E;;;;N;;;;; +2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;; +2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; +2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; +202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;; +202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;; +202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;; +202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;; +202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;; +202F;NARROW NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;;;;; +2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;; +2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; +2032;PRIME;Po;0;ET;;;;;N;;;;; +2033;DOUBLE PRIME;Po;0;ET; 2032 2032;;;;N;;;;; +2034;TRIPLE PRIME;Po;0;ET; 2032 2032 2032;;;;N;;;;; +2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;; +2036;REVERSED DOUBLE PRIME;Po;0;ON; 2035 2035;;;;N;;;;; +2037;REVERSED TRIPLE PRIME;Po;0;ON; 2035 2035 2035;;;;N;;;;; +2038;CARET;Po;0;ON;;;;;N;;;;; +2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;; +203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;; +203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;; +203C;DOUBLE EXCLAMATION MARK;Po;0;ON; 0021 0021;;;;N;;;;; +203D;INTERROBANG;Po;0;ON;;;;;N;;;;; +203E;OVERLINE;Po;0;ON; 0020 0305;;;;N;SPACING OVERSCORE;;;; +203F;UNDERTIE;Pc;0;ON;;;;;N;;Enotikon;;; +2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;; +2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;; +2042;ASTERISM;Po;0;ON;;;;;N;;;;; +2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;; +2044;FRACTION SLASH;Sm;0;CS;;;;;N;;;;; +2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;; +2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;; +2047;DOUBLE QUESTION MARK;Po;0;ON; 003F 003F;;;;N;;;;; +2048;QUESTION EXCLAMATION MARK;Po;0;ON; 003F 0021;;;;N;;;;; +2049;EXCLAMATION QUESTION MARK;Po;0;ON; 0021 003F;;;;N;;;;; +204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;; +204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;; +204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;; +204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;; +2050;CLOSE UP;Po;0;ON;;;;;N;;;;; +2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;; +2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2053;SWUNG DASH;Po;0;ON;;;;;N;;;;; +2054;INVERTED UNDERTIE;Pc;0;ON;;;;;N;;;;; +2055;FLOWER PUNCTUATION MARK;Po;0;ON;;;;;N;;;;; +2056;THREE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2057;QUADRUPLE PRIME;Po;0;ON; 2032 2032 2032 2032;;;;N;;;;; +2058;FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2059;FIVE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +205A;TWO DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +205B;FOUR DOT MARK;Po;0;ON;;;;;N;;;;; +205C;DOTTED CROSS;Po;0;ON;;;;;N;;;;; +205D;TRICOLON;Po;0;ON;;;;;N;;;;; +205E;VERTICAL FOUR DOTS;Po;0;ON;;;;;N;;;;; +205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS; 0020;;;;N;;;;; +2060;WORD JOINER;Cf;0;BN;;;;;N;;;;; +2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;; +2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;; +2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;; +2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;; +206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +2070;SUPERSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;; +2071;SUPERSCRIPT LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;;; +2074;SUPERSCRIPT FOUR;No;0;EN; 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;; +2075;SUPERSCRIPT FIVE;No;0;EN; 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;; +2076;SUPERSCRIPT SIX;No;0;EN; 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;; +2077;SUPERSCRIPT SEVEN;No;0;EN; 0037;;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;; +2078;SUPERSCRIPT EIGHT;No;0;EN; 0038;;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;; +2079;SUPERSCRIPT NINE;No;0;EN; 0039;;9;9;N;SUPERSCRIPT DIGIT NINE;;;; +207A;SUPERSCRIPT PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +207B;SUPERSCRIPT MINUS;Sm;0;ES; 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;; +207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;; +207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;; +207F;SUPERSCRIPT LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;;; +2080;SUBSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;; +2081;SUBSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;; +2082;SUBSCRIPT TWO;No;0;EN; 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;; +2083;SUBSCRIPT THREE;No;0;EN; 0033;;3;3;N;SUBSCRIPT DIGIT THREE;;;; +2084;SUBSCRIPT FOUR;No;0;EN; 0034;;4;4;N;SUBSCRIPT DIGIT FOUR;;;; +2085;SUBSCRIPT FIVE;No;0;EN; 0035;;5;5;N;SUBSCRIPT DIGIT FIVE;;;; +2086;SUBSCRIPT SIX;No;0;EN; 0036;;6;6;N;SUBSCRIPT DIGIT SIX;;;; +2087;SUBSCRIPT SEVEN;No;0;EN; 0037;;7;7;N;SUBSCRIPT DIGIT SEVEN;;;; +2088;SUBSCRIPT EIGHT;No;0;EN; 0038;;8;8;N;SUBSCRIPT DIGIT EIGHT;;;; +2089;SUBSCRIPT NINE;No;0;EN; 0039;;9;9;N;SUBSCRIPT DIGIT NINE;;;; +208A;SUBSCRIPT PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +208B;SUBSCRIPT MINUS;Sm;0;ES; 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;; +208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;; +208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;; +2090;LATIN SUBSCRIPT SMALL LETTER A;Lm;0;L; 0061;;;;N;;;;; +2091;LATIN SUBSCRIPT SMALL LETTER E;Lm;0;L; 0065;;;;N;;;;; +2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L; 006F;;;;N;;;;; +2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L; 0078;;;;N;;;;; +2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L; 0259;;;;N;;;;; +20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;; +20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;; +20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;; +20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;; +20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;; +20A8;RUPEE SIGN;Sc;0;ET; 0052 0073;;;;N;;;;; +20A9;WON SIGN;Sc;0;ET;;;;;N;;;;; +20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;; +20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;; +20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;; +20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;; +20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;; +20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;; +20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;; +20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;; +20B2;GUARANI SIGN;Sc;0;ET;;;;;N;;;;; +20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;; +20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;; +20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;; +20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; +20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; +20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; +20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;; +20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;; +20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;; +20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;; +20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;; +20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;; +20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;; +20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;; +20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;; +20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;; +20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;; +20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;; +20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;; +20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;; +20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;; +20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;; +20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;; +20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;; +20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;; +20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;; +20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;; +20EB;COMBINING LONG DOUBLE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; +20EC;COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;; +20ED;COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;; +20EE;COMBINING LEFT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +20EF;COMBINING RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +20F0;COMBINING ASTERISK ABOVE;Mn;230;NSM;;;;;N;;;;; +2100;ACCOUNT OF;So;0;ON; 0061 002F 0063;;;;N;;;;; +2101;ADDRESSED TO THE SUBJECT;So;0;ON; 0061 002F 0073;;;;N;;;;; +2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L; 0043;;;;N;DOUBLE-STRUCK C;;;; +2103;DEGREE CELSIUS;So;0;ON; 00B0 0043;;;;N;DEGREES CENTIGRADE;;;; +2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;; +2105;CARE OF;So;0;ON; 0063 002F 006F;;;;N;;;;; +2106;CADA UNA;So;0;ON; 0063 002F 0075;;;;N;;;;; +2107;EULER CONSTANT;Lu;0;L; 0190;;;;N;EULERS;;;; +2108;SCRUPLE;So;0;ON;;;;;N;;;;; +2109;DEGREE FAHRENHEIT;So;0;ON; 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;; +210A;SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +210B;SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;SCRIPT H;;;; +210C;BLACK-LETTER CAPITAL H;Lu;0;L; 0048;;;;N;BLACK-LETTER H;;;; +210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L; 0048;;;;N;DOUBLE-STRUCK H;;;; +210E;PLANCK CONSTANT;Ll;0;L; 0068;;;;N;;;;; +210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L; 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;; +2110;SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;SCRIPT I;;;; +2111;BLACK-LETTER CAPITAL I;Lu;0;L; 0049;;;;N;BLACK-LETTER I;;;; +2112;SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;SCRIPT L;;;; +2113;SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;; +2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L; 004E;;;;N;DOUBLE-STRUCK N;;;; +2116;NUMERO SIGN;So;0;ON; 004E 006F;;;;N;NUMERO;;;; +2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;; +2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;; +2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L; 0050;;;;N;DOUBLE-STRUCK P;;;; +211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L; 0051;;;;N;DOUBLE-STRUCK Q;;;; +211B;SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;SCRIPT R;;;; +211C;BLACK-LETTER CAPITAL R;Lu;0;L; 0052;;;;N;BLACK-LETTER R;;;; +211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L; 0052;;;;N;DOUBLE-STRUCK R;;;; +211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;; +211F;RESPONSE;So;0;ON;;;;;N;;;;; +2120;SERVICE MARK;So;0;ON; 0053 004D;;;;N;;;;; +2121;TELEPHONE SIGN;So;0;ON; 0054 0045 004C;;;;N;T E L SYMBOL;;;; +2122;TRADE MARK SIGN;So;0;ON; 0054 004D;;;;N;TRADEMARK;;;; +2123;VERSICLE;So;0;ON;;;;;N;;;;; +2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L; 005A;;;;N;DOUBLE-STRUCK Z;;;; +2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;; +2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9; +2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;; +2128;BLACK-LETTER CAPITAL Z;Lu;0;L; 005A;;;;N;BLACK-LETTER Z;;;; +2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;; +212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B; +212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5; +212C;SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;SCRIPT B;;;; +212D;BLACK-LETTER CAPITAL C;Lu;0;L; 0043;;;;N;BLACK-LETTER C;;;; +212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;; +212F;SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +2130;SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;SCRIPT E;;;; +2131;SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;SCRIPT F;;;; +2132;TURNED CAPITAL F;Lu;0;L;;;;;N;TURNED F;;;214E; +2133;SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;SCRIPT M;;;; +2134;SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +2135;ALEF SYMBOL;Lo;0;L; 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;; +2136;BET SYMBOL;Lo;0;L; 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;; +2137;GIMEL SYMBOL;Lo;0;L; 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;; +2138;DALET SYMBOL;Lo;0;L; 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;; +2139;INFORMATION SOURCE;Ll;0;L; 0069;;;;N;;;;; +213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;; +213B;FACSIMILE SIGN;So;0;ON; 0046 0041 0058;;;;N;;;;; +213C;DOUBLE-STRUCK SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON; 2211;;;;Y;;;;; +2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;; +2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;; +2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +214A;PROPERTY LINE;So;0;ON;;;;;N;;;;; +214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;; +214C;PER SIGN;So;0;ON;;;;;N;;;;; +214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;; +214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132 +214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;; +2153;VULGAR FRACTION ONE THIRD;No;0;ON; 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;; +2154;VULGAR FRACTION TWO THIRDS;No;0;ON; 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;; +2155;VULGAR FRACTION ONE FIFTH;No;0;ON; 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;; +2156;VULGAR FRACTION TWO FIFTHS;No;0;ON; 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;; +2157;VULGAR FRACTION THREE FIFTHS;No;0;ON; 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;; +2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON; 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;; +2159;VULGAR FRACTION ONE SIXTH;No;0;ON; 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;; +215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON; 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;; +215B;VULGAR FRACTION ONE EIGHTH;No;0;ON; 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;; +215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON; 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;; +215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON; 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;; +215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON; 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;; +215F;FRACTION NUMERATOR ONE;No;0;ON; 0031 2044;;;1;N;;;;; +2160;ROMAN NUMERAL ONE;Nl;0;L; 0049;;;1;N;;;;2170; +2161;ROMAN NUMERAL TWO;Nl;0;L; 0049 0049;;;2;N;;;;2171; +2162;ROMAN NUMERAL THREE;Nl;0;L; 0049 0049 0049;;;3;N;;;;2172; +2163;ROMAN NUMERAL FOUR;Nl;0;L; 0049 0056;;;4;N;;;;2173; +2164;ROMAN NUMERAL FIVE;Nl;0;L; 0056;;;5;N;;;;2174; +2165;ROMAN NUMERAL SIX;Nl;0;L; 0056 0049;;;6;N;;;;2175; +2166;ROMAN NUMERAL SEVEN;Nl;0;L; 0056 0049 0049;;;7;N;;;;2176; +2167;ROMAN NUMERAL EIGHT;Nl;0;L; 0056 0049 0049 0049;;;8;N;;;;2177; +2168;ROMAN NUMERAL NINE;Nl;0;L; 0049 0058;;;9;N;;;;2178; +2169;ROMAN NUMERAL TEN;Nl;0;L; 0058;;;10;N;;;;2179; +216A;ROMAN NUMERAL ELEVEN;Nl;0;L; 0058 0049;;;11;N;;;;217A; +216B;ROMAN NUMERAL TWELVE;Nl;0;L; 0058 0049 0049;;;12;N;;;;217B; +216C;ROMAN NUMERAL FIFTY;Nl;0;L; 004C;;;50;N;;;;217C; +216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0043;;;100;N;;;;217D; +216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0044;;;500;N;;;;217E; +216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 004D;;;1000;N;;;;217F; +2170;SMALL ROMAN NUMERAL ONE;Nl;0;L; 0069;;;1;N;;;2160;;2160 +2171;SMALL ROMAN NUMERAL TWO;Nl;0;L; 0069 0069;;;2;N;;;2161;;2161 +2172;SMALL ROMAN NUMERAL THREE;Nl;0;L; 0069 0069 0069;;;3;N;;;2162;;2162 +2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L; 0069 0076;;;4;N;;;2163;;2163 +2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L; 0076;;;5;N;;;2164;;2164 +2175;SMALL ROMAN NUMERAL SIX;Nl;0;L; 0076 0069;;;6;N;;;2165;;2165 +2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L; 0076 0069 0069;;;7;N;;;2166;;2166 +2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L; 0076 0069 0069 0069;;;8;N;;;2167;;2167 +2178;SMALL ROMAN NUMERAL NINE;Nl;0;L; 0069 0078;;;9;N;;;2168;;2168 +2179;SMALL ROMAN NUMERAL TEN;Nl;0;L; 0078;;;10;N;;;2169;;2169 +217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L; 0078 0069;;;11;N;;;216A;;216A +217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L; 0078 0069 0069;;;12;N;;;216B;;216B +217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L; 006C;;;50;N;;;216C;;216C +217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0063;;;100;N;;;216D;;216D +217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0064;;;500;N;;;216E;;216E +217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 006D;;;1000;N;;;216F;;216F +2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;; +2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;; +2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;; +2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L;;;;;N;;;;2184; +2184;LATIN SMALL LETTER REVERSED C;Ll;0;L;;;;;N;;;2183;;2183 +2185;ROMAN NUMERAL SIX LATE FORM;Nl;0;L;;;;6;N;;;;; +2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;; +2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;; +2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;; +2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;; +2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;; +2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;; +2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;; +2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;; +2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;; +2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;; +2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;; +2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;; +219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;; +219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;; +219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;; +219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;; +219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;; +219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;; +21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;; +21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;; +21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;; +21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;; +21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;; +21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;; +21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;; +21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;; +21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;; +21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;; +21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;; +21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;; +21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;; +21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;; +21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;; +21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;; +21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;; +21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;; +21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;; +21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;; +21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;; +21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;; +21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;; +21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;; +21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;; +21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;; +21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;; +21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;; +21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;; +21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;; +21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;; +21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;; +21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;; +21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;; +21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;; +21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;; +21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;; +21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;; +21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;; +21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;; +21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;; +21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;; +21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;; +21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;; +21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;; +21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;; +21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;; +21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;; +21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;; +21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;; +21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;; +21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;; +21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;; +21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;; +21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;; +21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;; +21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;; +21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;; +21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;; +21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;; +21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;; +21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;; +21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;; +21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;; +21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;; +21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;; +21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;; +21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;; +21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;; +21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; +21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;; +21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;; +21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;; +21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;; +21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; +21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +2200;FOR ALL;Sm;0;ON;;;;;N;;;;; +2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;; +2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;; +2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;; +2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;; +2205;EMPTY SET;Sm;0;ON;;;;;N;;;;; +2206;INCREMENT;Sm;0;ON;;;;;N;;;;; +2207;NABLA;Sm;0;ON;;;;;N;;;;; +2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;; +220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;; +220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220E;END OF PROOF;Sm;0;ON;;;;;N;;;;; +220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;; +2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;; +2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;; +2212;MINUS SIGN;Sm;0;ES;;;;;N;;;;; +2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;; +2214;DOT PLUS;Sm;0;ON;;;;;N;;;;; +2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2216;SET MINUS;Sm;0;ON;;;;;Y;;;;; +2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;; +2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;; +221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;; +221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;; +221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;; +221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;; +221E;INFINITY;Sm;0;ON;;;;;N;;;;; +221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;; +2220;ANGLE;Sm;0;ON;;;;;Y;;;;; +2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;; +2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;; +2223;DIVIDES;Sm;0;ON;;;;;N;;;;; +2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;; +2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;; +2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;; +2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2229;INTERSECTION;Sm;0;ON;;;;;N;;;;; +222A;UNION;Sm;0;ON;;;;;N;;;;; +222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222C;DOUBLE INTEGRAL;Sm;0;ON; 222B 222B;;;;Y;;;;; +222D;TRIPLE INTEGRAL;Sm;0;ON; 222B 222B 222B;;;;Y;;;;; +222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222F;SURFACE INTEGRAL;Sm;0;ON; 222E 222E;;;;Y;;;;; +2230;VOLUME INTEGRAL;Sm;0;ON; 222E 222E 222E;;;;Y;;;;; +2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2234;THEREFORE;Sm;0;ON;;;;;N;;;;; +2235;BECAUSE;Sm;0;ON;;;;;N;;;;; +2236;RATIO;Sm;0;ON;;;;;N;;;;; +2237;PROPORTION;Sm;0;ON;;;;;N;;;;; +2238;DOT MINUS;Sm;0;ON;;;;;N;;;;; +2239;EXCESS;Sm;0;ON;;;;;Y;;;;; +223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;; +223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;; +223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;lazy S;;; +223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;; +223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;; +2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;; +2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;; +2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;; +2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;; +2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;; +2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;; +224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;; +224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;; +2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;; +2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;; +2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;; +2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;; +2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;; +2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;; +2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;; +2259;ESTIMATES;Sm;0;ON;;;;;N;;;;; +225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;; +225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;; +225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;; +225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;; +225E;MEASURED BY;Sm;0;ON;;;;;N;;;;; +225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;; +2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;; +2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;; +2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;; +2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;; +2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;; +2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;; +2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;; +2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;; +226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;; +226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;; +226C;BETWEEN;Sm;0;ON;;;;;N;;;;; +226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;; +226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;; +226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;; +2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;; +2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;; +2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;; +2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;; +2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;; +2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;; +2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;; +2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;; +2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;; +2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;; +227A;PRECEDES;Sm;0;ON;;;;;Y;;;;; +227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;; +2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;; +2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;; +2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;; +2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;; +2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;; +2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;; +2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;; +228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;; +228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;; +228C;MULTISET;Sm;0;ON;;;;;Y;;;;; +228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;; +228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;; +228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;; +2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;; +2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;; +2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;; +2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;; +229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;; +229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;; +229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;; +229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;; +22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;; +22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;; +22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;; +22A5;UP TACK;Sm;0;ON;;;;;N;;;;; +22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;; +22A7;MODELS;Sm;0;ON;;;;;Y;;;;; +22A8;TRUE;Sm;0;ON;;;;;Y;;;;; +22A9;FORCES;Sm;0;ON;;;;;Y;;;;; +22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;; +22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;; +22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;; +22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;; +22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;; +22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;; +22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;; +22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;; +22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;; +22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;; +22BB;XOR;Sm;0;ON;;;;;N;;;;; +22BC;NAND;Sm;0;ON;;;;;N;;;;; +22BD;NOR;Sm;0;ON;;;;;N;;;;; +22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;; +22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;; +22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;; +22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;; +22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;; +22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;; +22C8;BOWTIE;Sm;0;ON;;;;;N;;;;; +22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;; +22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;; +22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;; +22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;; +22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;; +22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;; +22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;; +22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;; +22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;; +22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;; +22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;; +22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;; +22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;; +22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;; +22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;; +22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;; +22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;; +22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;; +22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;; +22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;; +22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;; +22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;; +22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;; +22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;; +22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;; +22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;; +22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;; +22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;; +2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;; +2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;; +2302;HOUSE;So;0;ON;;;;;N;;;;; +2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;; +2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;; +2305;PROJECTIVE;So;0;ON;;;;;N;;;;; +2306;PERSPECTIVE;So;0;ON;;;;;N;;;;; +2307;WAVY LINE;So;0;ON;;;;;N;;;;; +2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;; +2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;; +230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;; +230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;; +230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;; +230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;; +230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;; +230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;; +2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;; +2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;; +2312;ARC;So;0;ON;;;;;N;;;;; +2313;SEGMENT;So;0;ON;;;;;N;;;;; +2314;SECTOR;So;0;ON;;;;;N;;;;; +2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;; +2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;; +2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;; +2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;; +2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;; +231A;WATCH;So;0;ON;;;;;N;;;;; +231B;HOURGLASS;So;0;ON;;;;;N;;;;; +231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;; +231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;; +231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;; +231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;; +2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2322;FROWN;So;0;ON;;;;;N;;;;; +2323;SMILE;So;0;ON;;;;;N;;;;; +2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;; +2325;OPTION KEY;So;0;ON;;;;;N;;;;; +2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;; +2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;; +2328;KEYBOARD;So;0;ON;;;;;N;;;;; +2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;; +232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;; +232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;; +232C;BENZENE RING;So;0;ON;;;;;N;;;;; +232D;CYLINDRICITY;So;0;ON;;;;;N;;;;; +232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;; +232F;SYMMETRY;So;0;ON;;;;;N;;;;; +2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;; +2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;; +2332;CONICAL TAPER;So;0;ON;;;;;N;;;;; +2333;SLOPE;So;0;ON;;;;;N;;;;; +2334;COUNTERBORE;So;0;ON;;;;;N;;;;; +2335;COUNTERSINK;So;0;ON;;;;;N;;;;; +2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;; +2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;; +2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;; +2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;; +233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;; +233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;; +233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;; +233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;; +233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;; +233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;; +2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;; +2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;; +2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;; +2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;; +2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;; +2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;; +2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;; +2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;; +2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;; +2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;; +234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;*;;; +234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;; +234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;; +234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;; +234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;*;;; +234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;; +2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;; +2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;*;;; +2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;; +2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;; +2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;; +2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;*;;; +2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;; +2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;; +2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;; +2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;; +235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;; +235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;; +235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;; +235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;; +235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;; +235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;; +2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;; +2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;*;;; +2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;; +2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;; +2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;; +2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;; +2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;; +2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;; +2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;; +2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;; +236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;; +236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;; +236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;; +236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;; +236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;; +236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;; +2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;; +2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;; +2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;; +2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;; +2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;; +2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;; +2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;; +2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;; +2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;; +2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;; +237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;; +237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;; +237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;; +237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;; +237E;BELL SYMBOL;So;0;ON;;;;;N;;;;; +237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;; +2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;; +2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;; +2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;; +2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;; +2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;; +2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;; +2388;HELM SYMBOL;So;0;ON;;;;;N;;;;; +2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;pause;;; +238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;break;;; +238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;escape;;; +238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;; +238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;; +238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;; +238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;; +2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;; +2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;; +2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;; +2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;; +2398;NEXT PAGE;So;0;ON;;;;;N;;;;; +2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;; +23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;; +23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;; +23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;; +23B4;TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B5;BOTTOM SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;; +23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;; +23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;; +23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;; +23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;; +23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;; +23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;; +23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;; +23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;; +23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;; +23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;; +23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;; +23CF;EJECT SYMBOL;So;0;ON;;;;;N;;;;; +23D0;VERTICAL LINE EXTENSION;So;0;ON;;;;;N;;;;; +23D1;METRICAL BREVE;So;0;ON;;;;;N;;;;; +23D2;METRICAL LONG OVER SHORT;So;0;ON;;;;;N;;;;; +23D3;METRICAL SHORT OVER LONG;So;0;ON;;;;;N;;;;; +23D4;METRICAL LONG OVER TWO SHORTS;So;0;ON;;;;;N;;;;; +23D5;METRICAL TWO SHORTS OVER LONG;So;0;ON;;;;;N;;;;; +23D6;METRICAL TWO SHORTS JOINED;So;0;ON;;;;;N;;;;; +23D7;METRICAL TRISEME;So;0;ON;;;;;N;;;;; +23D8;METRICAL TETRASEME;So;0;ON;;;;;N;;;;; +23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;; +23DA;EARTH GROUND;So;0;ON;;;;;N;;;;; +23DB;FUSE;So;0;ON;;;;;N;;;;; +23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;mathematical use;;; +23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;mathematical use;;; +23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; +23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; +23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; +23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; +23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;; +23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;; +23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;; +23E5;FLATNESS;So;0;ON;;;;;N;;;;; +23E6;AC CURRENT;So;0;ON;;;;;N;;;;; +23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;; +2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;; +2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;; +2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;; +2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;; +2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;; +2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;; +2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;; +2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;; +2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;; +2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;; +240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;; +240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;; +240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;; +240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;; +240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;; +240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;; +2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;; +2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;; +2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;; +2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;; +2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;; +2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;; +2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;; +2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;; +2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;; +2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;; +241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;; +241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;; +241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;; +241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;; +241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;; +241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;; +2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;; +2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;; +2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;; +2423;OPEN BOX;So;0;ON;;;;;N;;;;; +2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;; +2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;; +2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;; +2440;OCR HOOK;So;0;ON;;;;;N;;;;; +2441;OCR CHAIR;So;0;ON;;;;;N;;;;; +2442;OCR FORK;So;0;ON;;;;;N;;;;; +2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;; +2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;; +2445;OCR BOW TIE;So;0;ON;;;;;N;;;;; +2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;; +2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;; +2448;OCR DASH;So;0;ON;;;;;N;;;;; +2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;; +244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;; +2460;CIRCLED DIGIT ONE;No;0;ON; 0031;;1;1;N;;;;; +2461;CIRCLED DIGIT TWO;No;0;ON; 0032;;2;2;N;;;;; +2462;CIRCLED DIGIT THREE;No;0;ON; 0033;;3;3;N;;;;; +2463;CIRCLED DIGIT FOUR;No;0;ON; 0034;;4;4;N;;;;; +2464;CIRCLED DIGIT FIVE;No;0;ON; 0035;;5;5;N;;;;; +2465;CIRCLED DIGIT SIX;No;0;ON; 0036;;6;6;N;;;;; +2466;CIRCLED DIGIT SEVEN;No;0;ON; 0037;;7;7;N;;;;; +2467;CIRCLED DIGIT EIGHT;No;0;ON; 0038;;8;8;N;;;;; +2468;CIRCLED DIGIT NINE;No;0;ON; 0039;;9;9;N;;;;; +2469;CIRCLED NUMBER TEN;No;0;ON; 0031 0030;;;10;N;;;;; +246A;CIRCLED NUMBER ELEVEN;No;0;ON; 0031 0031;;;11;N;;;;; +246B;CIRCLED NUMBER TWELVE;No;0;ON; 0031 0032;;;12;N;;;;; +246C;CIRCLED NUMBER THIRTEEN;No;0;ON; 0031 0033;;;13;N;;;;; +246D;CIRCLED NUMBER FOURTEEN;No;0;ON; 0031 0034;;;14;N;;;;; +246E;CIRCLED NUMBER FIFTEEN;No;0;ON; 0031 0035;;;15;N;;;;; +246F;CIRCLED NUMBER SIXTEEN;No;0;ON; 0031 0036;;;16;N;;;;; +2470;CIRCLED NUMBER SEVENTEEN;No;0;ON; 0031 0037;;;17;N;;;;; +2471;CIRCLED NUMBER EIGHTEEN;No;0;ON; 0031 0038;;;18;N;;;;; +2472;CIRCLED NUMBER NINETEEN;No;0;ON; 0031 0039;;;19;N;;;;; +2473;CIRCLED NUMBER TWENTY;No;0;ON; 0032 0030;;;20;N;;;;; +2474;PARENTHESIZED DIGIT ONE;No;0;ON; 0028 0031 0029;;1;1;N;;;;; +2475;PARENTHESIZED DIGIT TWO;No;0;ON; 0028 0032 0029;;2;2;N;;;;; +2476;PARENTHESIZED DIGIT THREE;No;0;ON; 0028 0033 0029;;3;3;N;;;;; +2477;PARENTHESIZED DIGIT FOUR;No;0;ON; 0028 0034 0029;;4;4;N;;;;; +2478;PARENTHESIZED DIGIT FIVE;No;0;ON; 0028 0035 0029;;5;5;N;;;;; +2479;PARENTHESIZED DIGIT SIX;No;0;ON; 0028 0036 0029;;6;6;N;;;;; +247A;PARENTHESIZED DIGIT SEVEN;No;0;ON; 0028 0037 0029;;7;7;N;;;;; +247B;PARENTHESIZED DIGIT EIGHT;No;0;ON; 0028 0038 0029;;8;8;N;;;;; +247C;PARENTHESIZED DIGIT NINE;No;0;ON; 0028 0039 0029;;9;9;N;;;;; +247D;PARENTHESIZED NUMBER TEN;No;0;ON; 0028 0031 0030 0029;;;10;N;;;;; +247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON; 0028 0031 0031 0029;;;11;N;;;;; +247F;PARENTHESIZED NUMBER TWELVE;No;0;ON; 0028 0031 0032 0029;;;12;N;;;;; +2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON; 0028 0031 0033 0029;;;13;N;;;;; +2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON; 0028 0031 0034 0029;;;14;N;;;;; +2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON; 0028 0031 0035 0029;;;15;N;;;;; +2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON; 0028 0031 0036 0029;;;16;N;;;;; +2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON; 0028 0031 0037 0029;;;17;N;;;;; +2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON; 0028 0031 0038 0029;;;18;N;;;;; +2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON; 0028 0031 0039 0029;;;19;N;;;;; +2487;PARENTHESIZED NUMBER TWENTY;No;0;ON; 0028 0032 0030 0029;;;20;N;;;;; +2488;DIGIT ONE FULL STOP;No;0;EN; 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;; +2489;DIGIT TWO FULL STOP;No;0;EN; 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;; +248A;DIGIT THREE FULL STOP;No;0;EN; 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;; +248B;DIGIT FOUR FULL STOP;No;0;EN; 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;; +248C;DIGIT FIVE FULL STOP;No;0;EN; 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;; +248D;DIGIT SIX FULL STOP;No;0;EN; 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;; +248E;DIGIT SEVEN FULL STOP;No;0;EN; 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;; +248F;DIGIT EIGHT FULL STOP;No;0;EN; 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;; +2490;DIGIT NINE FULL STOP;No;0;EN; 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;; +2491;NUMBER TEN FULL STOP;No;0;EN; 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;; +2492;NUMBER ELEVEN FULL STOP;No;0;EN; 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;; +2493;NUMBER TWELVE FULL STOP;No;0;EN; 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;; +2494;NUMBER THIRTEEN FULL STOP;No;0;EN; 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;; +2495;NUMBER FOURTEEN FULL STOP;No;0;EN; 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;; +2496;NUMBER FIFTEEN FULL STOP;No;0;EN; 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;; +2497;NUMBER SIXTEEN FULL STOP;No;0;EN; 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;; +2498;NUMBER SEVENTEEN FULL STOP;No;0;EN; 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;; +2499;NUMBER EIGHTEEN FULL STOP;No;0;EN; 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;; +249A;NUMBER NINETEEN FULL STOP;No;0;EN; 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;; +249B;NUMBER TWENTY FULL STOP;No;0;EN; 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;; +249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L; 0028 0061 0029;;;;N;;;;; +249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L; 0028 0062 0029;;;;N;;;;; +249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L; 0028 0063 0029;;;;N;;;;; +249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L; 0028 0064 0029;;;;N;;;;; +24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L; 0028 0065 0029;;;;N;;;;; +24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L; 0028 0066 0029;;;;N;;;;; +24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L; 0028 0067 0029;;;;N;;;;; +24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L; 0028 0068 0029;;;;N;;;;; +24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L; 0028 0069 0029;;;;N;;;;; +24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L; 0028 006A 0029;;;;N;;;;; +24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L; 0028 006B 0029;;;;N;;;;; +24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L; 0028 006C 0029;;;;N;;;;; +24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L; 0028 006D 0029;;;;N;;;;; +24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L; 0028 006E 0029;;;;N;;;;; +24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L; 0028 006F 0029;;;;N;;;;; +24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L; 0028 0070 0029;;;;N;;;;; +24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L; 0028 0071 0029;;;;N;;;;; +24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L; 0028 0072 0029;;;;N;;;;; +24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L; 0028 0073 0029;;;;N;;;;; +24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L; 0028 0074 0029;;;;N;;;;; +24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L; 0028 0075 0029;;;;N;;;;; +24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L; 0028 0076 0029;;;;N;;;;; +24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L; 0028 0077 0029;;;;N;;;;; +24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L; 0028 0078 0029;;;;N;;;;; +24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L; 0028 0079 0029;;;;N;;;;; +24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L; 0028 007A 0029;;;;N;;;;; +24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L; 0041;;;;N;;;;24D0; +24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;24D1; +24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;24D2; +24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L; 0044;;;;N;;;;24D3; +24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L; 0045;;;;N;;;;24D4; +24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L; 0046;;;;N;;;;24D5; +24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L; 0047;;;;N;;;;24D6; +24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L; 0048;;;;N;;;;24D7; +24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L; 0049;;;;N;;;;24D8; +24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L; 004A;;;;N;;;;24D9; +24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L; 004B;;;;N;;;;24DA; +24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L; 004C;;;;N;;;;24DB; +24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L; 004D;;;;N;;;;24DC; +24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;24DD; +24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L; 004F;;;;N;;;;24DE; +24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;24DF; +24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L; 0051;;;;N;;;;24E0; +24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;24E1; +24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;24E2; +24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L; 0054;;;;N;;;;24E3; +24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L; 0055;;;;N;;;;24E4; +24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L; 0056;;;;N;;;;24E5; +24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;24E6; +24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L; 0058;;;;N;;;;24E7; +24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L; 0059;;;;N;;;;24E8; +24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L; 005A;;;;N;;;;24E9; +24D0;CIRCLED LATIN SMALL LETTER A;So;0;L; 0061;;;;N;;;24B6;;24B6 +24D1;CIRCLED LATIN SMALL LETTER B;So;0;L; 0062;;;;N;;;24B7;;24B7 +24D2;CIRCLED LATIN SMALL LETTER C;So;0;L; 0063;;;;N;;;24B8;;24B8 +24D3;CIRCLED LATIN SMALL LETTER D;So;0;L; 0064;;;;N;;;24B9;;24B9 +24D4;CIRCLED LATIN SMALL LETTER E;So;0;L; 0065;;;;N;;;24BA;;24BA +24D5;CIRCLED LATIN SMALL LETTER F;So;0;L; 0066;;;;N;;;24BB;;24BB +24D6;CIRCLED LATIN SMALL LETTER G;So;0;L; 0067;;;;N;;;24BC;;24BC +24D7;CIRCLED LATIN SMALL LETTER H;So;0;L; 0068;;;;N;;;24BD;;24BD +24D8;CIRCLED LATIN SMALL LETTER I;So;0;L; 0069;;;;N;;;24BE;;24BE +24D9;CIRCLED LATIN SMALL LETTER J;So;0;L; 006A;;;;N;;;24BF;;24BF +24DA;CIRCLED LATIN SMALL LETTER K;So;0;L; 006B;;;;N;;;24C0;;24C0 +24DB;CIRCLED LATIN SMALL LETTER L;So;0;L; 006C;;;;N;;;24C1;;24C1 +24DC;CIRCLED LATIN SMALL LETTER M;So;0;L; 006D;;;;N;;;24C2;;24C2 +24DD;CIRCLED LATIN SMALL LETTER N;So;0;L; 006E;;;;N;;;24C3;;24C3 +24DE;CIRCLED LATIN SMALL LETTER O;So;0;L; 006F;;;;N;;;24C4;;24C4 +24DF;CIRCLED LATIN SMALL LETTER P;So;0;L; 0070;;;;N;;;24C5;;24C5 +24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L; 0071;;;;N;;;24C6;;24C6 +24E1;CIRCLED LATIN SMALL LETTER R;So;0;L; 0072;;;;N;;;24C7;;24C7 +24E2;CIRCLED LATIN SMALL LETTER S;So;0;L; 0073;;;;N;;;24C8;;24C8 +24E3;CIRCLED LATIN SMALL LETTER T;So;0;L; 0074;;;;N;;;24C9;;24C9 +24E4;CIRCLED LATIN SMALL LETTER U;So;0;L; 0075;;;;N;;;24CA;;24CA +24E5;CIRCLED LATIN SMALL LETTER V;So;0;L; 0076;;;;N;;;24CB;;24CB +24E6;CIRCLED LATIN SMALL LETTER W;So;0;L; 0077;;;;N;;;24CC;;24CC +24E7;CIRCLED LATIN SMALL LETTER X;So;0;L; 0078;;;;N;;;24CD;;24CD +24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L; 0079;;;;N;;;24CE;;24CE +24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L; 007A;;;;N;;;24CF;;24CF +24EA;CIRCLED DIGIT ZERO;No;0;ON; 0030;;0;0;N;;;;; +24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;; +24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;; +24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;; +24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;; +24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;; +24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;; +24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;; +24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;; +24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;; +24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;; +24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;; +24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;; +24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;; +24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;; +24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;; +24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;; +24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;; +24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;; +24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;; +24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;; +24FF;NEGATIVE CIRCLED DIGIT ZERO;No;0;ON;;;0;0;N;;;;; +2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;; +2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;; +2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;; +2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;; +2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;; +2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;; +2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;; +2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;; +2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;; +2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;; +250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;; +250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;; +250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;; +250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;; +250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;; +250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;; +2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;; +2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;; +2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;; +2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;; +2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;; +2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;; +2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;; +2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;; +2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;; +2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;; +251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;; +251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;; +251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;; +251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;; +251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;; +251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;; +2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;; +2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;; +2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;; +2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;; +2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;; +2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;; +2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;; +2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;; +2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;; +2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;; +252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;; +252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;; +252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;; +252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;; +252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;; +252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;; +2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;; +2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;; +2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;; +2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;; +2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;; +2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;; +2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;; +2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;; +2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;; +2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;; +253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;; +253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;; +253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;; +253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;; +253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;; +253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;; +2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;; +2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;; +2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;; +2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;; +2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;; +2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;; +2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;; +2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;; +2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;; +2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;; +254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;; +254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;; +254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;; +254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;; +254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;; +254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;; +2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;; +2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;; +2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;; +2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;; +2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;; +2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;; +2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;; +2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;; +2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;; +2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;; +255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;; +255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;; +255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;; +255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;; +255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;; +255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;; +2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;; +2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;; +2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;; +2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;; +2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;; +2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;; +2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;; +2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;; +2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;; +2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;; +256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;; +256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;; +256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;; +256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;; +256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;; +256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;; +2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;; +2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;; +2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;; +2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;; +2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;; +2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;; +2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;; +2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;; +2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;; +2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;; +257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;; +257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;; +257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;; +257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;; +257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;; +257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;; +2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;; +2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;; +2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;; +2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2588;FULL BLOCK;So;0;ON;;;;;N;;;;; +2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;; +258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;; +258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;; +2591;LIGHT SHADE;So;0;ON;;;;;N;;;;; +2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;; +2593;DARK SHADE;So;0;ON;;;;;N;;;;; +2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;; +2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;; +2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;; +2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;; +259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;; +25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;; +25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;; +25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;; +25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;; +25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;; +25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;; +25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;; +25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;; +25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;; +25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;; +25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;; +25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;; +25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;; +25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;; +25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;; +25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;; +25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;; +25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;; +25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;; +25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;; +25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;; +25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;; +25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;; +25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;; +25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;; +25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;; +25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;; +25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;; +25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;; +25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; +25C9;FISHEYE;So;0;ON;;;;;N;;;;; +25CA;LOZENGE;So;0;ON;;;;;N;;;;; +25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;; +25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25CE;BULLSEYE;So;0;ON;;;;;N;;;;; +25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;; +25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;; +25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;; +25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E6;WHITE BULLET;So;0;ON;;;;;N;;;;; +25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;; +25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;; +25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;; +25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;; +25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;; +25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;; +2601;CLOUD;So;0;ON;;;;;N;;;;; +2602;UMBRELLA;So;0;ON;;;;;N;;;;; +2603;SNOWMAN;So;0;ON;;;;;N;;;;; +2604;COMET;So;0;ON;;;;;N;;;;; +2605;BLACK STAR;So;0;ON;;;;;N;;;;; +2606;WHITE STAR;So;0;ON;;;;;N;;;;; +2607;LIGHTNING;So;0;ON;;;;;N;;;;; +2608;THUNDERSTORM;So;0;ON;;;;;N;;;;; +2609;SUN;So;0;ON;;;;;N;;;;; +260A;ASCENDING NODE;So;0;ON;;;;;N;;;;; +260B;DESCENDING NODE;So;0;ON;;;;;N;;;;; +260C;CONJUNCTION;So;0;ON;;;;;N;;;;; +260D;OPPOSITION;So;0;ON;;;;;N;;;;; +260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;; +260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;; +2610;BALLOT BOX;So;0;ON;;;;;N;;;;; +2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;; +2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;; +2613;SALTIRE;So;0;ON;;;;;N;;;;; +2614;UMBRELLA WITH RAIN DROPS;So;0;ON;;;;;N;;;;; +2615;HOT BEVERAGE;So;0;ON;;;;;N;;;;; +2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; +2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; +2618;SHAMROCK;So;0;ON;;;;;N;;;;; +2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;; +261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;; +2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;; +2621;CAUTION SIGN;So;0;ON;;;;;N;;;;; +2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;; +2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;; +2624;CADUCEUS;So;0;ON;;;;;N;;;;; +2625;ANKH;So;0;ON;;;;;N;;;;; +2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;; +2627;CHI RHO;So;0;ON;;;;;N;;;;; +2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;; +2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;; +262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;; +262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;; +262C;ADI SHAKTI;So;0;ON;;;;;N;;;;; +262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;; +262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;; +262F;YIN YANG;So;0;ON;;;;;N;;;;; +2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;; +2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;; +2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;; +2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;; +2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;; +2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;; +2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;; +2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;; +2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;; +263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;; +263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;; +263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;; +263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;; +263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;; +263F;MERCURY;So;0;ON;;;;;N;;;;; +2640;FEMALE SIGN;So;0;ON;;;;;N;;;;; +2641;EARTH;So;0;ON;;;;;N;;;;; +2642;MALE SIGN;So;0;ON;;;;;N;;;;; +2643;JUPITER;So;0;ON;;;;;N;;;;; +2644;SATURN;So;0;ON;;;;;N;;;;; +2645;URANUS;So;0;ON;;;;;N;;;;; +2646;NEPTUNE;So;0;ON;;;;;N;;;;; +2647;PLUTO;So;0;ON;;;;;N;;;;; +2648;ARIES;So;0;ON;;;;;N;;;;; +2649;TAURUS;So;0;ON;;;;;N;;;;; +264A;GEMINI;So;0;ON;;;;;N;;;;; +264B;CANCER;So;0;ON;;;;;N;;;;; +264C;LEO;So;0;ON;;;;;N;;;;; +264D;VIRGO;So;0;ON;;;;;N;;;;; +264E;LIBRA;So;0;ON;;;;;N;;;;; +264F;SCORPIUS;So;0;ON;;;;;N;;;;; +2650;SAGITTARIUS;So;0;ON;;;;;N;;;;; +2651;CAPRICORN;So;0;ON;;;;;N;;;;; +2652;AQUARIUS;So;0;ON;;;;;N;;;;; +2653;PISCES;So;0;ON;;;;;N;;;;; +2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;; +2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;; +2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;; +2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;; +2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;; +2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;; +265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;; +265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;; +265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;; +265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;; +265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;; +265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;; +2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;; +2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;; +2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;; +2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;; +2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;; +2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;; +2668;HOT SPRINGS;So;0;ON;;;;;N;;;;; +2669;QUARTER NOTE;So;0;ON;;;;;N;;;;; +266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;; +266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;; +266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;; +266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;; +266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;; +266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;; +2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;pete;;; +2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;hdpe;;; +2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;pvc;;; +2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;ldpe;;; +2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;pp;;; +2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;ps;;; +2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;other;;; +267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;; +267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +267E;PERMANENT PAPER SIGN;So;0;ON;;;;;N;;;;; +267F;WHEELCHAIR SYMBOL;So;0;ON;;;;;N;;;;; +2680;DIE FACE-1;So;0;ON;;;;;N;;;;; +2681;DIE FACE-2;So;0;ON;;;;;N;;;;; +2682;DIE FACE-3;So;0;ON;;;;;N;;;;; +2683;DIE FACE-4;So;0;ON;;;;;N;;;;; +2684;DIE FACE-5;So;0;ON;;;;;N;;;;; +2685;DIE FACE-6;So;0;ON;;;;;N;;;;; +2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;; +2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;; +2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;; +268A;MONOGRAM FOR YANG;So;0;ON;;;;;N;;;;; +268B;MONOGRAM FOR YIN;So;0;ON;;;;;N;;;;; +268C;DIGRAM FOR GREATER YANG;So;0;ON;;;;;N;;;;; +268D;DIGRAM FOR LESSER YIN;So;0;ON;;;;;N;;;;; +268E;DIGRAM FOR LESSER YANG;So;0;ON;;;;;N;;;;; +268F;DIGRAM FOR GREATER YIN;So;0;ON;;;;;N;;;;; +2690;WHITE FLAG;So;0;ON;;;;;N;;;;; +2691;BLACK FLAG;So;0;ON;;;;;N;;;;; +2692;HAMMER AND PICK;So;0;ON;;;;;N;;;;; +2693;ANCHOR;So;0;ON;;;;;N;;;;; +2694;CROSSED SWORDS;So;0;ON;;;;;N;;;;; +2695;STAFF OF AESCULAPIUS;So;0;ON;;;;;N;;;;; +2696;SCALES;So;0;ON;;;;;N;;;;; +2697;ALEMBIC;So;0;ON;;;;;N;;;;; +2698;FLOWER;So;0;ON;;;;;N;;;;; +2699;GEAR;So;0;ON;;;;;N;;;;; +269A;STAFF OF HERMES;So;0;ON;;;;;N;;;;; +269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;; +269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;; +269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +26A0;WARNING SIGN;So;0;ON;;;;;N;;;;; +26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;; +26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A3;DOUBLED MALE SIGN;So;0;ON;;;;;N;;;;; +26A4;INTERLOCKED FEMALE AND MALE SIGN;So;0;ON;;;;;N;;;;; +26A5;MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A6;MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26A7;MALE WITH STROKE AND MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A8;VERTICAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26A9;HORIZONTAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26AA;MEDIUM WHITE CIRCLE;So;0;ON;;;;;N;;;;; +26AB;MEDIUM BLACK CIRCLE;So;0;ON;;;;;N;;;;; +26AC;MEDIUM SMALL WHITE CIRCLE;So;0;L;;;;;N;;;;; +26AD;MARRIAGE SYMBOL;So;0;ON;;;;;N;;;;; +26AE;DIVORCE SYMBOL;So;0;ON;;;;;N;;;;; +26AF;UNMARRIED PARTNERSHIP SYMBOL;So;0;ON;;;;;N;;;;; +26B0;COFFIN;So;0;ON;;;;;N;;;;; +26B1;FUNERAL URN;So;0;ON;;;;;N;;;;; +26B2;NEUTER;So;0;ON;;;;;N;;;;; +26B3;CERES;So;0;ON;;;;;N;;;;; +26B4;PALLAS;So;0;ON;;;;;N;;;;; +26B5;JUNO;So;0;ON;;;;;N;;;;; +26B6;VESTA;So;0;ON;;;;;N;;;;; +26B7;CHIRON;So;0;ON;;;;;N;;;;; +26B8;BLACK MOON LILITH;So;0;ON;;;;;N;;;;; +26B9;SEXTILE;So;0;ON;;;;;N;;;;; +26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;; +26BB;QUINCUNX;So;0;ON;;;;;N;;;;; +26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;; +26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;; +26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;; +26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;; +26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;; +2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;; +2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;; +2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;; +2707;TAPE DRIVE;So;0;ON;;;;;N;;;;; +2708;AIRPLANE;So;0;ON;;;;;N;;;;; +2709;ENVELOPE;So;0;ON;;;;;N;;;;; +270C;VICTORY HAND;So;0;ON;;;;;N;;;;; +270D;WRITING HAND;So;0;ON;;;;;N;;;;; +270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +270F;PENCIL;So;0;ON;;;;;N;;;;; +2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +2711;WHITE NIB;So;0;ON;;;;;N;;;;; +2712;BLACK NIB;So;0;ON;;;;;N;;;;; +2713;CHECK MARK;So;0;ON;;;;;N;;;;; +2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;; +2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2717;BALLOT X;So;0;ON;;;;;N;;;;; +2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;; +2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;; +271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;; +271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;; +271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;; +271D;LATIN CROSS;So;0;ON;;;;;N;;;;; +271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;; +271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;; +2720;MALTESE CROSS;So;0;ON;;;;;N;;;;; +2721;STAR OF DAVID;So;0;ON;;;;;N;;;;; +2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;; +272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;; +272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;; +272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;; +2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;; +2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;; +2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;; +273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;; +273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;; +273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;; +2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;; +2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;; +2744;SNOWFLAKE;So;0;ON;;;;;N;;;;; +2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;; +2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;; +2747;SPARKLE;So;0;ON;;;;;N;;;;; +2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;; +2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;; +274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;; +2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;; +2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;; +275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;; +275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;; +2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;; +2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;; +2766;FLORAL HEART;So;0;ON;;;;;N;;;;; +2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;; +2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;; +2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;; +2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;; +277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;; +277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;; +277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;; +277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;; +277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;; +277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;; +2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;; +2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;; +2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;; +2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;; +2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;; +2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;; +2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;; +2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;; +278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;; +278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;; +278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;; +278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;; +278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;; +278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;; +2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;; +2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;; +2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;; +2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;; +2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;; +279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;; +279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;; +279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;; +279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;; +279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;; +279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;; +27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;; +27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;; +27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;; +27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;; +27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;; +27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;; +27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;; +27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;; +27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;; +27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;; +27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;; +27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;; +27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;; +27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;; +27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;; +27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;; +27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;; +27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;; +27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;; +27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;; +27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;; +27C3;OPEN SUBSET;Sm;0;ON;;;;;Y;;;;; +27C4;OPEN SUPERSET;Sm;0;ON;;;;;Y;;;;; +27C5;LEFT S-SHAPED BAG DELIMITER;Ps;0;ON;;;;;Y;;;;; +27C6;RIGHT S-SHAPED BAG DELIMITER;Pe;0;ON;;;;;Y;;;;; +27C7;OR WITH DOT INSIDE;Sm;0;ON;;;;;N;;;;; +27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;; +27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;; +27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;; +27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;; +27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;; +27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;; +27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;; +27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;; +27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;; +27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;; +27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;; +27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;; +27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;; +27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;; +27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;; +27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;; +27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27EC;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; +27ED;MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; +27EE;MATHEMATICAL LEFT FLATTENED PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +27EF;MATHEMATICAL RIGHT FLATTENED PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; +2800;BRAILLE PATTERN BLANK;So;0;L;;;;;N;;;;; +2801;BRAILLE PATTERN DOTS-1;So;0;L;;;;;N;;;;; +2802;BRAILLE PATTERN DOTS-2;So;0;L;;;;;N;;;;; +2803;BRAILLE PATTERN DOTS-12;So;0;L;;;;;N;;;;; +2804;BRAILLE PATTERN DOTS-3;So;0;L;;;;;N;;;;; +2805;BRAILLE PATTERN DOTS-13;So;0;L;;;;;N;;;;; +2806;BRAILLE PATTERN DOTS-23;So;0;L;;;;;N;;;;; +2807;BRAILLE PATTERN DOTS-123;So;0;L;;;;;N;;;;; +2808;BRAILLE PATTERN DOTS-4;So;0;L;;;;;N;;;;; +2809;BRAILLE PATTERN DOTS-14;So;0;L;;;;;N;;;;; +280A;BRAILLE PATTERN DOTS-24;So;0;L;;;;;N;;;;; +280B;BRAILLE PATTERN DOTS-124;So;0;L;;;;;N;;;;; +280C;BRAILLE PATTERN DOTS-34;So;0;L;;;;;N;;;;; +280D;BRAILLE PATTERN DOTS-134;So;0;L;;;;;N;;;;; +280E;BRAILLE PATTERN DOTS-234;So;0;L;;;;;N;;;;; +280F;BRAILLE PATTERN DOTS-1234;So;0;L;;;;;N;;;;; +2810;BRAILLE PATTERN DOTS-5;So;0;L;;;;;N;;;;; +2811;BRAILLE PATTERN DOTS-15;So;0;L;;;;;N;;;;; +2812;BRAILLE PATTERN DOTS-25;So;0;L;;;;;N;;;;; +2813;BRAILLE PATTERN DOTS-125;So;0;L;;;;;N;;;;; +2814;BRAILLE PATTERN DOTS-35;So;0;L;;;;;N;;;;; +2815;BRAILLE PATTERN DOTS-135;So;0;L;;;;;N;;;;; +2816;BRAILLE PATTERN DOTS-235;So;0;L;;;;;N;;;;; +2817;BRAILLE PATTERN DOTS-1235;So;0;L;;;;;N;;;;; +2818;BRAILLE PATTERN DOTS-45;So;0;L;;;;;N;;;;; +2819;BRAILLE PATTERN DOTS-145;So;0;L;;;;;N;;;;; +281A;BRAILLE PATTERN DOTS-245;So;0;L;;;;;N;;;;; +281B;BRAILLE PATTERN DOTS-1245;So;0;L;;;;;N;;;;; +281C;BRAILLE PATTERN DOTS-345;So;0;L;;;;;N;;;;; +281D;BRAILLE PATTERN DOTS-1345;So;0;L;;;;;N;;;;; +281E;BRAILLE PATTERN DOTS-2345;So;0;L;;;;;N;;;;; +281F;BRAILLE PATTERN DOTS-12345;So;0;L;;;;;N;;;;; +2820;BRAILLE PATTERN DOTS-6;So;0;L;;;;;N;;;;; +2821;BRAILLE PATTERN DOTS-16;So;0;L;;;;;N;;;;; +2822;BRAILLE PATTERN DOTS-26;So;0;L;;;;;N;;;;; +2823;BRAILLE PATTERN DOTS-126;So;0;L;;;;;N;;;;; +2824;BRAILLE PATTERN DOTS-36;So;0;L;;;;;N;;;;; +2825;BRAILLE PATTERN DOTS-136;So;0;L;;;;;N;;;;; +2826;BRAILLE PATTERN DOTS-236;So;0;L;;;;;N;;;;; +2827;BRAILLE PATTERN DOTS-1236;So;0;L;;;;;N;;;;; +2828;BRAILLE PATTERN DOTS-46;So;0;L;;;;;N;;;;; +2829;BRAILLE PATTERN DOTS-146;So;0;L;;;;;N;;;;; +282A;BRAILLE PATTERN DOTS-246;So;0;L;;;;;N;;;;; +282B;BRAILLE PATTERN DOTS-1246;So;0;L;;;;;N;;;;; +282C;BRAILLE PATTERN DOTS-346;So;0;L;;;;;N;;;;; +282D;BRAILLE PATTERN DOTS-1346;So;0;L;;;;;N;;;;; +282E;BRAILLE PATTERN DOTS-2346;So;0;L;;;;;N;;;;; +282F;BRAILLE PATTERN DOTS-12346;So;0;L;;;;;N;;;;; +2830;BRAILLE PATTERN DOTS-56;So;0;L;;;;;N;;;;; +2831;BRAILLE PATTERN DOTS-156;So;0;L;;;;;N;;;;; +2832;BRAILLE PATTERN DOTS-256;So;0;L;;;;;N;;;;; +2833;BRAILLE PATTERN DOTS-1256;So;0;L;;;;;N;;;;; +2834;BRAILLE PATTERN DOTS-356;So;0;L;;;;;N;;;;; +2835;BRAILLE PATTERN DOTS-1356;So;0;L;;;;;N;;;;; +2836;BRAILLE PATTERN DOTS-2356;So;0;L;;;;;N;;;;; +2837;BRAILLE PATTERN DOTS-12356;So;0;L;;;;;N;;;;; +2838;BRAILLE PATTERN DOTS-456;So;0;L;;;;;N;;;;; +2839;BRAILLE PATTERN DOTS-1456;So;0;L;;;;;N;;;;; +283A;BRAILLE PATTERN DOTS-2456;So;0;L;;;;;N;;;;; +283B;BRAILLE PATTERN DOTS-12456;So;0;L;;;;;N;;;;; +283C;BRAILLE PATTERN DOTS-3456;So;0;L;;;;;N;;;;; +283D;BRAILLE PATTERN DOTS-13456;So;0;L;;;;;N;;;;; +283E;BRAILLE PATTERN DOTS-23456;So;0;L;;;;;N;;;;; +283F;BRAILLE PATTERN DOTS-123456;So;0;L;;;;;N;;;;; +2840;BRAILLE PATTERN DOTS-7;So;0;L;;;;;N;;;;; +2841;BRAILLE PATTERN DOTS-17;So;0;L;;;;;N;;;;; +2842;BRAILLE PATTERN DOTS-27;So;0;L;;;;;N;;;;; +2843;BRAILLE PATTERN DOTS-127;So;0;L;;;;;N;;;;; +2844;BRAILLE PATTERN DOTS-37;So;0;L;;;;;N;;;;; +2845;BRAILLE PATTERN DOTS-137;So;0;L;;;;;N;;;;; +2846;BRAILLE PATTERN DOTS-237;So;0;L;;;;;N;;;;; +2847;BRAILLE PATTERN DOTS-1237;So;0;L;;;;;N;;;;; +2848;BRAILLE PATTERN DOTS-47;So;0;L;;;;;N;;;;; +2849;BRAILLE PATTERN DOTS-147;So;0;L;;;;;N;;;;; +284A;BRAILLE PATTERN DOTS-247;So;0;L;;;;;N;;;;; +284B;BRAILLE PATTERN DOTS-1247;So;0;L;;;;;N;;;;; +284C;BRAILLE PATTERN DOTS-347;So;0;L;;;;;N;;;;; +284D;BRAILLE PATTERN DOTS-1347;So;0;L;;;;;N;;;;; +284E;BRAILLE PATTERN DOTS-2347;So;0;L;;;;;N;;;;; +284F;BRAILLE PATTERN DOTS-12347;So;0;L;;;;;N;;;;; +2850;BRAILLE PATTERN DOTS-57;So;0;L;;;;;N;;;;; +2851;BRAILLE PATTERN DOTS-157;So;0;L;;;;;N;;;;; +2852;BRAILLE PATTERN DOTS-257;So;0;L;;;;;N;;;;; +2853;BRAILLE PATTERN DOTS-1257;So;0;L;;;;;N;;;;; +2854;BRAILLE PATTERN DOTS-357;So;0;L;;;;;N;;;;; +2855;BRAILLE PATTERN DOTS-1357;So;0;L;;;;;N;;;;; +2856;BRAILLE PATTERN DOTS-2357;So;0;L;;;;;N;;;;; +2857;BRAILLE PATTERN DOTS-12357;So;0;L;;;;;N;;;;; +2858;BRAILLE PATTERN DOTS-457;So;0;L;;;;;N;;;;; +2859;BRAILLE PATTERN DOTS-1457;So;0;L;;;;;N;;;;; +285A;BRAILLE PATTERN DOTS-2457;So;0;L;;;;;N;;;;; +285B;BRAILLE PATTERN DOTS-12457;So;0;L;;;;;N;;;;; +285C;BRAILLE PATTERN DOTS-3457;So;0;L;;;;;N;;;;; +285D;BRAILLE PATTERN DOTS-13457;So;0;L;;;;;N;;;;; +285E;BRAILLE PATTERN DOTS-23457;So;0;L;;;;;N;;;;; +285F;BRAILLE PATTERN DOTS-123457;So;0;L;;;;;N;;;;; +2860;BRAILLE PATTERN DOTS-67;So;0;L;;;;;N;;;;; +2861;BRAILLE PATTERN DOTS-167;So;0;L;;;;;N;;;;; +2862;BRAILLE PATTERN DOTS-267;So;0;L;;;;;N;;;;; +2863;BRAILLE PATTERN DOTS-1267;So;0;L;;;;;N;;;;; +2864;BRAILLE PATTERN DOTS-367;So;0;L;;;;;N;;;;; +2865;BRAILLE PATTERN DOTS-1367;So;0;L;;;;;N;;;;; +2866;BRAILLE PATTERN DOTS-2367;So;0;L;;;;;N;;;;; +2867;BRAILLE PATTERN DOTS-12367;So;0;L;;;;;N;;;;; +2868;BRAILLE PATTERN DOTS-467;So;0;L;;;;;N;;;;; +2869;BRAILLE PATTERN DOTS-1467;So;0;L;;;;;N;;;;; +286A;BRAILLE PATTERN DOTS-2467;So;0;L;;;;;N;;;;; +286B;BRAILLE PATTERN DOTS-12467;So;0;L;;;;;N;;;;; +286C;BRAILLE PATTERN DOTS-3467;So;0;L;;;;;N;;;;; +286D;BRAILLE PATTERN DOTS-13467;So;0;L;;;;;N;;;;; +286E;BRAILLE PATTERN DOTS-23467;So;0;L;;;;;N;;;;; +286F;BRAILLE PATTERN DOTS-123467;So;0;L;;;;;N;;;;; +2870;BRAILLE PATTERN DOTS-567;So;0;L;;;;;N;;;;; +2871;BRAILLE PATTERN DOTS-1567;So;0;L;;;;;N;;;;; +2872;BRAILLE PATTERN DOTS-2567;So;0;L;;;;;N;;;;; +2873;BRAILLE PATTERN DOTS-12567;So;0;L;;;;;N;;;;; +2874;BRAILLE PATTERN DOTS-3567;So;0;L;;;;;N;;;;; +2875;BRAILLE PATTERN DOTS-13567;So;0;L;;;;;N;;;;; +2876;BRAILLE PATTERN DOTS-23567;So;0;L;;;;;N;;;;; +2877;BRAILLE PATTERN DOTS-123567;So;0;L;;;;;N;;;;; +2878;BRAILLE PATTERN DOTS-4567;So;0;L;;;;;N;;;;; +2879;BRAILLE PATTERN DOTS-14567;So;0;L;;;;;N;;;;; +287A;BRAILLE PATTERN DOTS-24567;So;0;L;;;;;N;;;;; +287B;BRAILLE PATTERN DOTS-124567;So;0;L;;;;;N;;;;; +287C;BRAILLE PATTERN DOTS-34567;So;0;L;;;;;N;;;;; +287D;BRAILLE PATTERN DOTS-134567;So;0;L;;;;;N;;;;; +287E;BRAILLE PATTERN DOTS-234567;So;0;L;;;;;N;;;;; +287F;BRAILLE PATTERN DOTS-1234567;So;0;L;;;;;N;;;;; +2880;BRAILLE PATTERN DOTS-8;So;0;L;;;;;N;;;;; +2881;BRAILLE PATTERN DOTS-18;So;0;L;;;;;N;;;;; +2882;BRAILLE PATTERN DOTS-28;So;0;L;;;;;N;;;;; +2883;BRAILLE PATTERN DOTS-128;So;0;L;;;;;N;;;;; +2884;BRAILLE PATTERN DOTS-38;So;0;L;;;;;N;;;;; +2885;BRAILLE PATTERN DOTS-138;So;0;L;;;;;N;;;;; +2886;BRAILLE PATTERN DOTS-238;So;0;L;;;;;N;;;;; +2887;BRAILLE PATTERN DOTS-1238;So;0;L;;;;;N;;;;; +2888;BRAILLE PATTERN DOTS-48;So;0;L;;;;;N;;;;; +2889;BRAILLE PATTERN DOTS-148;So;0;L;;;;;N;;;;; +288A;BRAILLE PATTERN DOTS-248;So;0;L;;;;;N;;;;; +288B;BRAILLE PATTERN DOTS-1248;So;0;L;;;;;N;;;;; +288C;BRAILLE PATTERN DOTS-348;So;0;L;;;;;N;;;;; +288D;BRAILLE PATTERN DOTS-1348;So;0;L;;;;;N;;;;; +288E;BRAILLE PATTERN DOTS-2348;So;0;L;;;;;N;;;;; +288F;BRAILLE PATTERN DOTS-12348;So;0;L;;;;;N;;;;; +2890;BRAILLE PATTERN DOTS-58;So;0;L;;;;;N;;;;; +2891;BRAILLE PATTERN DOTS-158;So;0;L;;;;;N;;;;; +2892;BRAILLE PATTERN DOTS-258;So;0;L;;;;;N;;;;; +2893;BRAILLE PATTERN DOTS-1258;So;0;L;;;;;N;;;;; +2894;BRAILLE PATTERN DOTS-358;So;0;L;;;;;N;;;;; +2895;BRAILLE PATTERN DOTS-1358;So;0;L;;;;;N;;;;; +2896;BRAILLE PATTERN DOTS-2358;So;0;L;;;;;N;;;;; +2897;BRAILLE PATTERN DOTS-12358;So;0;L;;;;;N;;;;; +2898;BRAILLE PATTERN DOTS-458;So;0;L;;;;;N;;;;; +2899;BRAILLE PATTERN DOTS-1458;So;0;L;;;;;N;;;;; +289A;BRAILLE PATTERN DOTS-2458;So;0;L;;;;;N;;;;; +289B;BRAILLE PATTERN DOTS-12458;So;0;L;;;;;N;;;;; +289C;BRAILLE PATTERN DOTS-3458;So;0;L;;;;;N;;;;; +289D;BRAILLE PATTERN DOTS-13458;So;0;L;;;;;N;;;;; +289E;BRAILLE PATTERN DOTS-23458;So;0;L;;;;;N;;;;; +289F;BRAILLE PATTERN DOTS-123458;So;0;L;;;;;N;;;;; +28A0;BRAILLE PATTERN DOTS-68;So;0;L;;;;;N;;;;; +28A1;BRAILLE PATTERN DOTS-168;So;0;L;;;;;N;;;;; +28A2;BRAILLE PATTERN DOTS-268;So;0;L;;;;;N;;;;; +28A3;BRAILLE PATTERN DOTS-1268;So;0;L;;;;;N;;;;; +28A4;BRAILLE PATTERN DOTS-368;So;0;L;;;;;N;;;;; +28A5;BRAILLE PATTERN DOTS-1368;So;0;L;;;;;N;;;;; +28A6;BRAILLE PATTERN DOTS-2368;So;0;L;;;;;N;;;;; +28A7;BRAILLE PATTERN DOTS-12368;So;0;L;;;;;N;;;;; +28A8;BRAILLE PATTERN DOTS-468;So;0;L;;;;;N;;;;; +28A9;BRAILLE PATTERN DOTS-1468;So;0;L;;;;;N;;;;; +28AA;BRAILLE PATTERN DOTS-2468;So;0;L;;;;;N;;;;; +28AB;BRAILLE PATTERN DOTS-12468;So;0;L;;;;;N;;;;; +28AC;BRAILLE PATTERN DOTS-3468;So;0;L;;;;;N;;;;; +28AD;BRAILLE PATTERN DOTS-13468;So;0;L;;;;;N;;;;; +28AE;BRAILLE PATTERN DOTS-23468;So;0;L;;;;;N;;;;; +28AF;BRAILLE PATTERN DOTS-123468;So;0;L;;;;;N;;;;; +28B0;BRAILLE PATTERN DOTS-568;So;0;L;;;;;N;;;;; +28B1;BRAILLE PATTERN DOTS-1568;So;0;L;;;;;N;;;;; +28B2;BRAILLE PATTERN DOTS-2568;So;0;L;;;;;N;;;;; +28B3;BRAILLE PATTERN DOTS-12568;So;0;L;;;;;N;;;;; +28B4;BRAILLE PATTERN DOTS-3568;So;0;L;;;;;N;;;;; +28B5;BRAILLE PATTERN DOTS-13568;So;0;L;;;;;N;;;;; +28B6;BRAILLE PATTERN DOTS-23568;So;0;L;;;;;N;;;;; +28B7;BRAILLE PATTERN DOTS-123568;So;0;L;;;;;N;;;;; +28B8;BRAILLE PATTERN DOTS-4568;So;0;L;;;;;N;;;;; +28B9;BRAILLE PATTERN DOTS-14568;So;0;L;;;;;N;;;;; +28BA;BRAILLE PATTERN DOTS-24568;So;0;L;;;;;N;;;;; +28BB;BRAILLE PATTERN DOTS-124568;So;0;L;;;;;N;;;;; +28BC;BRAILLE PATTERN DOTS-34568;So;0;L;;;;;N;;;;; +28BD;BRAILLE PATTERN DOTS-134568;So;0;L;;;;;N;;;;; +28BE;BRAILLE PATTERN DOTS-234568;So;0;L;;;;;N;;;;; +28BF;BRAILLE PATTERN DOTS-1234568;So;0;L;;;;;N;;;;; +28C0;BRAILLE PATTERN DOTS-78;So;0;L;;;;;N;;;;; +28C1;BRAILLE PATTERN DOTS-178;So;0;L;;;;;N;;;;; +28C2;BRAILLE PATTERN DOTS-278;So;0;L;;;;;N;;;;; +28C3;BRAILLE PATTERN DOTS-1278;So;0;L;;;;;N;;;;; +28C4;BRAILLE PATTERN DOTS-378;So;0;L;;;;;N;;;;; +28C5;BRAILLE PATTERN DOTS-1378;So;0;L;;;;;N;;;;; +28C6;BRAILLE PATTERN DOTS-2378;So;0;L;;;;;N;;;;; +28C7;BRAILLE PATTERN DOTS-12378;So;0;L;;;;;N;;;;; +28C8;BRAILLE PATTERN DOTS-478;So;0;L;;;;;N;;;;; +28C9;BRAILLE PATTERN DOTS-1478;So;0;L;;;;;N;;;;; +28CA;BRAILLE PATTERN DOTS-2478;So;0;L;;;;;N;;;;; +28CB;BRAILLE PATTERN DOTS-12478;So;0;L;;;;;N;;;;; +28CC;BRAILLE PATTERN DOTS-3478;So;0;L;;;;;N;;;;; +28CD;BRAILLE PATTERN DOTS-13478;So;0;L;;;;;N;;;;; +28CE;BRAILLE PATTERN DOTS-23478;So;0;L;;;;;N;;;;; +28CF;BRAILLE PATTERN DOTS-123478;So;0;L;;;;;N;;;;; +28D0;BRAILLE PATTERN DOTS-578;So;0;L;;;;;N;;;;; +28D1;BRAILLE PATTERN DOTS-1578;So;0;L;;;;;N;;;;; +28D2;BRAILLE PATTERN DOTS-2578;So;0;L;;;;;N;;;;; +28D3;BRAILLE PATTERN DOTS-12578;So;0;L;;;;;N;;;;; +28D4;BRAILLE PATTERN DOTS-3578;So;0;L;;;;;N;;;;; +28D5;BRAILLE PATTERN DOTS-13578;So;0;L;;;;;N;;;;; +28D6;BRAILLE PATTERN DOTS-23578;So;0;L;;;;;N;;;;; +28D7;BRAILLE PATTERN DOTS-123578;So;0;L;;;;;N;;;;; +28D8;BRAILLE PATTERN DOTS-4578;So;0;L;;;;;N;;;;; +28D9;BRAILLE PATTERN DOTS-14578;So;0;L;;;;;N;;;;; +28DA;BRAILLE PATTERN DOTS-24578;So;0;L;;;;;N;;;;; +28DB;BRAILLE PATTERN DOTS-124578;So;0;L;;;;;N;;;;; +28DC;BRAILLE PATTERN DOTS-34578;So;0;L;;;;;N;;;;; +28DD;BRAILLE PATTERN DOTS-134578;So;0;L;;;;;N;;;;; +28DE;BRAILLE PATTERN DOTS-234578;So;0;L;;;;;N;;;;; +28DF;BRAILLE PATTERN DOTS-1234578;So;0;L;;;;;N;;;;; +28E0;BRAILLE PATTERN DOTS-678;So;0;L;;;;;N;;;;; +28E1;BRAILLE PATTERN DOTS-1678;So;0;L;;;;;N;;;;; +28E2;BRAILLE PATTERN DOTS-2678;So;0;L;;;;;N;;;;; +28E3;BRAILLE PATTERN DOTS-12678;So;0;L;;;;;N;;;;; +28E4;BRAILLE PATTERN DOTS-3678;So;0;L;;;;;N;;;;; +28E5;BRAILLE PATTERN DOTS-13678;So;0;L;;;;;N;;;;; +28E6;BRAILLE PATTERN DOTS-23678;So;0;L;;;;;N;;;;; +28E7;BRAILLE PATTERN DOTS-123678;So;0;L;;;;;N;;;;; +28E8;BRAILLE PATTERN DOTS-4678;So;0;L;;;;;N;;;;; +28E9;BRAILLE PATTERN DOTS-14678;So;0;L;;;;;N;;;;; +28EA;BRAILLE PATTERN DOTS-24678;So;0;L;;;;;N;;;;; +28EB;BRAILLE PATTERN DOTS-124678;So;0;L;;;;;N;;;;; +28EC;BRAILLE PATTERN DOTS-34678;So;0;L;;;;;N;;;;; +28ED;BRAILLE PATTERN DOTS-134678;So;0;L;;;;;N;;;;; +28EE;BRAILLE PATTERN DOTS-234678;So;0;L;;;;;N;;;;; +28EF;BRAILLE PATTERN DOTS-1234678;So;0;L;;;;;N;;;;; +28F0;BRAILLE PATTERN DOTS-5678;So;0;L;;;;;N;;;;; +28F1;BRAILLE PATTERN DOTS-15678;So;0;L;;;;;N;;;;; +28F2;BRAILLE PATTERN DOTS-25678;So;0;L;;;;;N;;;;; +28F3;BRAILLE PATTERN DOTS-125678;So;0;L;;;;;N;;;;; +28F4;BRAILLE PATTERN DOTS-35678;So;0;L;;;;;N;;;;; +28F5;BRAILLE PATTERN DOTS-135678;So;0;L;;;;;N;;;;; +28F6;BRAILLE PATTERN DOTS-235678;So;0;L;;;;;N;;;;; +28F7;BRAILLE PATTERN DOTS-1235678;So;0;L;;;;;N;;;;; +28F8;BRAILLE PATTERN DOTS-45678;So;0;L;;;;;N;;;;; +28F9;BRAILLE PATTERN DOTS-145678;So;0;L;;;;;N;;;;; +28FA;BRAILLE PATTERN DOTS-245678;So;0;L;;;;;N;;;;; +28FB;BRAILLE PATTERN DOTS-1245678;So;0;L;;;;;N;;;;; +28FC;BRAILLE PATTERN DOTS-345678;So;0;L;;;;;N;;;;; +28FD;BRAILLE PATTERN DOTS-1345678;So;0;L;;;;;N;;;;; +28FE;BRAILLE PATTERN DOTS-2345678;So;0;L;;;;;N;;;;; +28FF;BRAILLE PATTERN DOTS-12345678;So;0;L;;;;;N;;;;; +2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; +2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; +2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;; +2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;; +2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;; +2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;; +2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;; +293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;; +293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; +2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;; +2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;; +2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;; +297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;; +297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;; +2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;; +2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;; +2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;; +2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;; +2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;; +2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;; +2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;; +2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;; +298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;; +298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;; +298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;; +298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;; +298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;; +298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;; +2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;; +2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;; +2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;; +2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; +2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; +2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;; +299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;; +299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;; +299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;; +299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;; +299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;; +29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;; +29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;; +29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;; +29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;; +29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;; +29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;; +29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;; +29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;; +29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;; +29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;; +29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;; +29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;; +29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;; +29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;; +29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;; +29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;; +29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;; +29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;; +29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;; +29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;; +29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;; +29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;; +29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;; +29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;; +29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;; +29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;; +29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;; +29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;; +29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;; +29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;; +29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;; +29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;; +29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;; +29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;; +29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +29FE;TINY;Sm;0;ON;;;;;N;;;;; +29FF;MINY;Sm;0;ON;;;;;N;;;;; +2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;; +2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;; +2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;; +2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;; +2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;; +2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;; +2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON; 222B 222B 222B 222B;;;;Y;;;;; +2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;; +2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;; +2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;; +2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;; +2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;; +2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;; +2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;; +2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;; +2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;; +2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2A1D;JOIN;Sm;0;ON;;;;;N;;;;; +2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;; +2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;; +2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;; +2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;; +2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;; +2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;; +2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;; +2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;; +2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;; +2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;; +2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;; +2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;; +2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;; +2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;; +2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;; +2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;; +2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;; +2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;; +2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;; +2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;; +2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A74;DOUBLE COLON EQUAL;Sm;0;ON; 003A 003A 003D;;;;Y;;;;; +2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D;;;;N;;;;; +2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D 003D;;;;N;;;;; +2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;; +2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;; +2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;; +2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;; +2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;; +2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;; +2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;; +2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;; +2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;; +2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;; +2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;; +2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;; +2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;not independent;;; +2ADD;NONFORKING;Sm;0;ON;;;;;N;;independent;;; +2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;; +2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;; +2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;; +2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;; +2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;; +2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;; +2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;; +2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;; +2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;; +2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;; +2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2B00;NORTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B01;NORTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B02;SOUTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B03;SOUTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B04;LEFT RIGHT WHITE ARROW;So;0;ON;;;;;N;;;;; +2B05;LEFTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B06;UPWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B07;DOWNWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B08;NORTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B09;NORTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0A;SOUTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0B;SOUTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0C;LEFT RIGHT BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0D;UP DOWN BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0E;RIGHTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2B0F;RIGHTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;; +2B10;LEFTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2B11;LEFTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;; +2B12;SQUARE WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;; +2B13;SQUARE WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;; +2B14;SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +2B15;SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +2B16;DIAMOND WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +2B17;DIAMOND WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +2B18;DIAMOND WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;; +2B19;DIAMOND WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;; +2B1A;DOTTED SQUARE;So;0;ON;;;;;N;;;;; +2B1B;BLACK LARGE SQUARE;So;0;ON;;;;;N;;;;; +2B1C;WHITE LARGE SQUARE;So;0;ON;;;;;N;;;;; +2B1D;BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +2B1E;WHITE VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +2B1F;BLACK PENTAGON;So;0;ON;;;;;N;;;;; +2B20;WHITE PENTAGON;So;0;ON;;;;;N;;;;; +2B21;WHITE HEXAGON;So;0;ON;;;;;N;;;;; +2B22;BLACK HEXAGON;So;0;ON;;;;;N;;;;; +2B23;HORIZONTAL BLACK HEXAGON;So;0;ON;;;;;N;;;;; +2B24;BLACK LARGE CIRCLE;So;0;ON;;;;;N;;;;; +2B25;BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;; +2B26;WHITE MEDIUM DIAMOND;So;0;ON;;;;;N;;;;; +2B27;BLACK MEDIUM LOZENGE;So;0;ON;;;;;N;;;;; +2B28;WHITE MEDIUM LOZENGE;So;0;ON;;;;;N;;;;; +2B29;BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; +2B2A;BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;; +2B2B;WHITE SMALL LOZENGE;So;0;ON;;;;;N;;;;; +2B2C;BLACK HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2D;WHITE HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2E;BLACK VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2F;WHITE VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B30;LEFT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +2B31;THREE LEFTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; +2B32;LEFT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +2B33;LONG LEFTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; +2B34;LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B35;LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B36;LEFTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2B37;LEFTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2B38;LEFTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; +2B39;LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3A;LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3B;LEFTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; +2B3C;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3D;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3E;LEFTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; +2B3F;WAVE ARROW POINTING DIRECTLY LEFT;Sm;0;ON;;;;;N;;;;; +2B40;EQUALS SIGN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B41;REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B42;LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B43;RIGHTWARDS ARROW THROUGH GREATER-THAN;Sm;0;ON;;;;;N;;;;; +2B44;RIGHTWARDS ARROW THROUGH SUPERSET;Sm;0;ON;;;;;N;;;;; +2B45;LEFTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;; +2B46;RIGHTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;; +2B47;REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B48;RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B49;TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;; +2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;; +2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;; +2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; +2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; +2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30; +2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31; +2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32; +2C03;GLAGOLITIC CAPITAL LETTER GLAGOLI;Lu;0;L;;;;;N;;;;2C33; +2C04;GLAGOLITIC CAPITAL LETTER DOBRO;Lu;0;L;;;;;N;;;;2C34; +2C05;GLAGOLITIC CAPITAL LETTER YESTU;Lu;0;L;;;;;N;;;;2C35; +2C06;GLAGOLITIC CAPITAL LETTER ZHIVETE;Lu;0;L;;;;;N;;;;2C36; +2C07;GLAGOLITIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;2C37; +2C08;GLAGOLITIC CAPITAL LETTER ZEMLJA;Lu;0;L;;;;;N;;;;2C38; +2C09;GLAGOLITIC CAPITAL LETTER IZHE;Lu;0;L;;;;;N;;;;2C39; +2C0A;GLAGOLITIC CAPITAL LETTER INITIAL IZHE;Lu;0;L;;;;;N;;;;2C3A; +2C0B;GLAGOLITIC CAPITAL LETTER I;Lu;0;L;;;;;N;;;;2C3B; +2C0C;GLAGOLITIC CAPITAL LETTER DJERVI;Lu;0;L;;;;;N;;;;2C3C; +2C0D;GLAGOLITIC CAPITAL LETTER KAKO;Lu;0;L;;;;;N;;;;2C3D; +2C0E;GLAGOLITIC CAPITAL LETTER LJUDIJE;Lu;0;L;;;;;N;;;;2C3E; +2C0F;GLAGOLITIC CAPITAL LETTER MYSLITE;Lu;0;L;;;;;N;;;;2C3F; +2C10;GLAGOLITIC CAPITAL LETTER NASHI;Lu;0;L;;;;;N;;;;2C40; +2C11;GLAGOLITIC CAPITAL LETTER ONU;Lu;0;L;;;;;N;;;;2C41; +2C12;GLAGOLITIC CAPITAL LETTER POKOJI;Lu;0;L;;;;;N;;;;2C42; +2C13;GLAGOLITIC CAPITAL LETTER RITSI;Lu;0;L;;;;;N;;;;2C43; +2C14;GLAGOLITIC CAPITAL LETTER SLOVO;Lu;0;L;;;;;N;;;;2C44; +2C15;GLAGOLITIC CAPITAL LETTER TVRIDO;Lu;0;L;;;;;N;;;;2C45; +2C16;GLAGOLITIC CAPITAL LETTER UKU;Lu;0;L;;;;;N;;;;2C46; +2C17;GLAGOLITIC CAPITAL LETTER FRITU;Lu;0;L;;;;;N;;;;2C47; +2C18;GLAGOLITIC CAPITAL LETTER HERU;Lu;0;L;;;;;N;;;;2C48; +2C19;GLAGOLITIC CAPITAL LETTER OTU;Lu;0;L;;;;;N;;;;2C49; +2C1A;GLAGOLITIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;2C4A; +2C1B;GLAGOLITIC CAPITAL LETTER SHTA;Lu;0;L;;;;;N;;;;2C4B; +2C1C;GLAGOLITIC CAPITAL LETTER TSI;Lu;0;L;;;;;N;;;;2C4C; +2C1D;GLAGOLITIC CAPITAL LETTER CHRIVI;Lu;0;L;;;;;N;;;;2C4D; +2C1E;GLAGOLITIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;2C4E; +2C1F;GLAGOLITIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;;;;2C4F; +2C20;GLAGOLITIC CAPITAL LETTER YERI;Lu;0;L;;;;;N;;;;2C50; +2C21;GLAGOLITIC CAPITAL LETTER YATI;Lu;0;L;;;;;N;;;;2C51; +2C22;GLAGOLITIC CAPITAL LETTER SPIDERY HA;Lu;0;L;;;;;N;;;;2C52; +2C23;GLAGOLITIC CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;2C53; +2C24;GLAGOLITIC CAPITAL LETTER SMALL YUS;Lu;0;L;;;;;N;;;;2C54; +2C25;GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL;Lu;0;L;;;;;N;;;;2C55; +2C26;GLAGOLITIC CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;2C56; +2C27;GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS;Lu;0;L;;;;;N;;;;2C57; +2C28;GLAGOLITIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;2C58; +2C29;GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS;Lu;0;L;;;;;N;;;;2C59; +2C2A;GLAGOLITIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;2C5A; +2C2B;GLAGOLITIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;2C5B; +2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C; +2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D; +2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E; +2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00 +2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01 +2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02 +2C33;GLAGOLITIC SMALL LETTER GLAGOLI;Ll;0;L;;;;;N;;;2C03;;2C03 +2C34;GLAGOLITIC SMALL LETTER DOBRO;Ll;0;L;;;;;N;;;2C04;;2C04 +2C35;GLAGOLITIC SMALL LETTER YESTU;Ll;0;L;;;;;N;;;2C05;;2C05 +2C36;GLAGOLITIC SMALL LETTER ZHIVETE;Ll;0;L;;;;;N;;;2C06;;2C06 +2C37;GLAGOLITIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;2C07;;2C07 +2C38;GLAGOLITIC SMALL LETTER ZEMLJA;Ll;0;L;;;;;N;;;2C08;;2C08 +2C39;GLAGOLITIC SMALL LETTER IZHE;Ll;0;L;;;;;N;;;2C09;;2C09 +2C3A;GLAGOLITIC SMALL LETTER INITIAL IZHE;Ll;0;L;;;;;N;;;2C0A;;2C0A +2C3B;GLAGOLITIC SMALL LETTER I;Ll;0;L;;;;;N;;;2C0B;;2C0B +2C3C;GLAGOLITIC SMALL LETTER DJERVI;Ll;0;L;;;;;N;;;2C0C;;2C0C +2C3D;GLAGOLITIC SMALL LETTER KAKO;Ll;0;L;;;;;N;;;2C0D;;2C0D +2C3E;GLAGOLITIC SMALL LETTER LJUDIJE;Ll;0;L;;;;;N;;;2C0E;;2C0E +2C3F;GLAGOLITIC SMALL LETTER MYSLITE;Ll;0;L;;;;;N;;;2C0F;;2C0F +2C40;GLAGOLITIC SMALL LETTER NASHI;Ll;0;L;;;;;N;;;2C10;;2C10 +2C41;GLAGOLITIC SMALL LETTER ONU;Ll;0;L;;;;;N;;;2C11;;2C11 +2C42;GLAGOLITIC SMALL LETTER POKOJI;Ll;0;L;;;;;N;;;2C12;;2C12 +2C43;GLAGOLITIC SMALL LETTER RITSI;Ll;0;L;;;;;N;;;2C13;;2C13 +2C44;GLAGOLITIC SMALL LETTER SLOVO;Ll;0;L;;;;;N;;;2C14;;2C14 +2C45;GLAGOLITIC SMALL LETTER TVRIDO;Ll;0;L;;;;;N;;;2C15;;2C15 +2C46;GLAGOLITIC SMALL LETTER UKU;Ll;0;L;;;;;N;;;2C16;;2C16 +2C47;GLAGOLITIC SMALL LETTER FRITU;Ll;0;L;;;;;N;;;2C17;;2C17 +2C48;GLAGOLITIC SMALL LETTER HERU;Ll;0;L;;;;;N;;;2C18;;2C18 +2C49;GLAGOLITIC SMALL LETTER OTU;Ll;0;L;;;;;N;;;2C19;;2C19 +2C4A;GLAGOLITIC SMALL LETTER PE;Ll;0;L;;;;;N;;;2C1A;;2C1A +2C4B;GLAGOLITIC SMALL LETTER SHTA;Ll;0;L;;;;;N;;;2C1B;;2C1B +2C4C;GLAGOLITIC SMALL LETTER TSI;Ll;0;L;;;;;N;;;2C1C;;2C1C +2C4D;GLAGOLITIC SMALL LETTER CHRIVI;Ll;0;L;;;;;N;;;2C1D;;2C1D +2C4E;GLAGOLITIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;2C1E;;2C1E +2C4F;GLAGOLITIC SMALL LETTER YERU;Ll;0;L;;;;;N;;;2C1F;;2C1F +2C50;GLAGOLITIC SMALL LETTER YERI;Ll;0;L;;;;;N;;;2C20;;2C20 +2C51;GLAGOLITIC SMALL LETTER YATI;Ll;0;L;;;;;N;;;2C21;;2C21 +2C52;GLAGOLITIC SMALL LETTER SPIDERY HA;Ll;0;L;;;;;N;;;2C22;;2C22 +2C53;GLAGOLITIC SMALL LETTER YU;Ll;0;L;;;;;N;;;2C23;;2C23 +2C54;GLAGOLITIC SMALL LETTER SMALL YUS;Ll;0;L;;;;;N;;;2C24;;2C24 +2C55;GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL;Ll;0;L;;;;;N;;;2C25;;2C25 +2C56;GLAGOLITIC SMALL LETTER YO;Ll;0;L;;;;;N;;;2C26;;2C26 +2C57;GLAGOLITIC SMALL LETTER IOTATED SMALL YUS;Ll;0;L;;;;;N;;;2C27;;2C27 +2C58;GLAGOLITIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;2C28;;2C28 +2C59;GLAGOLITIC SMALL LETTER IOTATED BIG YUS;Ll;0;L;;;;;N;;;2C29;;2C29 +2C5A;GLAGOLITIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;2C2A;;2C2A +2C5B;GLAGOLITIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;2C2B;;2C2B +2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C +2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D +2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E +2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61; +2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60 +2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B; +2C63;LATIN CAPITAL LETTER P WITH STROKE;Lu;0;L;;;;;N;;;;1D7D; +2C64;LATIN CAPITAL LETTER R WITH TAIL;Lu;0;L;;;;;N;;;;027D; +2C65;LATIN SMALL LETTER A WITH STROKE;Ll;0;L;;;;;N;;;023A;;023A +2C66;LATIN SMALL LETTER T WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;023E;;023E +2C67;LATIN CAPITAL LETTER H WITH DESCENDER;Lu;0;L;;;;;N;;;;2C68; +2C68;LATIN SMALL LETTER H WITH DESCENDER;Ll;0;L;;;;;N;;;2C67;;2C67 +2C69;LATIN CAPITAL LETTER K WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6A; +2C6A;LATIN SMALL LETTER K WITH DESCENDER;Ll;0;L;;;;;N;;;2C69;;2C69 +2C6B;LATIN CAPITAL LETTER Z WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6C; +2C6C;LATIN SMALL LETTER Z WITH DESCENDER;Ll;0;L;;;;;N;;;2C6B;;2C6B +2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251; +2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271; +2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250; +2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;; +2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73; +2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72 +2C74;LATIN SMALL LETTER V WITH CURL;Ll;0;L;;;;;N;;;;; +2C75;LATIN CAPITAL LETTER HALF H;Lu;0;L;;;;;N;;;;2C76; +2C76;LATIN SMALL LETTER HALF H;Ll;0;L;;;;;N;;;2C75;;2C75 +2C77;LATIN SMALL LETTER TAILLESS PHI;Ll;0;L;;;;;N;;;;; +2C78;LATIN SMALL LETTER E WITH NOTCH;Ll;0;L;;;;;N;;;;; +2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;; +2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;; +2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;; +2C7C;LATIN SUBSCRIPT SMALL LETTER J;Ll;0;L; 006A;;;;N;;;;; +2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L; 0056;;;;N;;;;; +2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81; +2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80 +2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83; +2C83;COPTIC SMALL LETTER VIDA;Ll;0;L;;;;;N;;;2C82;;2C82 +2C84;COPTIC CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;2C85; +2C85;COPTIC SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;2C84;;2C84 +2C86;COPTIC CAPITAL LETTER DALDA;Lu;0;L;;;;;N;;;;2C87; +2C87;COPTIC SMALL LETTER DALDA;Ll;0;L;;;;;N;;;2C86;;2C86 +2C88;COPTIC CAPITAL LETTER EIE;Lu;0;L;;;;;N;;;;2C89; +2C89;COPTIC SMALL LETTER EIE;Ll;0;L;;;;;N;;;2C88;;2C88 +2C8A;COPTIC CAPITAL LETTER SOU;Lu;0;L;;;;;N;;;;2C8B; +2C8B;COPTIC SMALL LETTER SOU;Ll;0;L;;;;;N;;;2C8A;;2C8A +2C8C;COPTIC CAPITAL LETTER ZATA;Lu;0;L;;;;;N;;;;2C8D; +2C8D;COPTIC SMALL LETTER ZATA;Ll;0;L;;;;;N;;;2C8C;;2C8C +2C8E;COPTIC CAPITAL LETTER HATE;Lu;0;L;;;;;N;;;;2C8F; +2C8F;COPTIC SMALL LETTER HATE;Ll;0;L;;;;;N;;;2C8E;;2C8E +2C90;COPTIC CAPITAL LETTER THETHE;Lu;0;L;;;;;N;;;;2C91; +2C91;COPTIC SMALL LETTER THETHE;Ll;0;L;;;;;N;;;2C90;;2C90 +2C92;COPTIC CAPITAL LETTER IAUDA;Lu;0;L;;;;;N;;;;2C93; +2C93;COPTIC SMALL LETTER IAUDA;Ll;0;L;;;;;N;;;2C92;;2C92 +2C94;COPTIC CAPITAL LETTER KAPA;Lu;0;L;;;;;N;;;;2C95; +2C95;COPTIC SMALL LETTER KAPA;Ll;0;L;;;;;N;;;2C94;;2C94 +2C96;COPTIC CAPITAL LETTER LAULA;Lu;0;L;;;;;N;;;;2C97; +2C97;COPTIC SMALL LETTER LAULA;Ll;0;L;;;;;N;;;2C96;;2C96 +2C98;COPTIC CAPITAL LETTER MI;Lu;0;L;;;;;N;;;;2C99; +2C99;COPTIC SMALL LETTER MI;Ll;0;L;;;;;N;;;2C98;;2C98 +2C9A;COPTIC CAPITAL LETTER NI;Lu;0;L;;;;;N;;;;2C9B; +2C9B;COPTIC SMALL LETTER NI;Ll;0;L;;;;;N;;;2C9A;;2C9A +2C9C;COPTIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;2C9D; +2C9D;COPTIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;2C9C;;2C9C +2C9E;COPTIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;2C9F; +2C9F;COPTIC SMALL LETTER O;Ll;0;L;;;;;N;;;2C9E;;2C9E +2CA0;COPTIC CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;2CA1; +2CA1;COPTIC SMALL LETTER PI;Ll;0;L;;;;;N;;;2CA0;;2CA0 +2CA2;COPTIC CAPITAL LETTER RO;Lu;0;L;;;;;N;;;;2CA3; +2CA3;COPTIC SMALL LETTER RO;Ll;0;L;;;;;N;;;2CA2;;2CA2 +2CA4;COPTIC CAPITAL LETTER SIMA;Lu;0;L;;;;;N;;;;2CA5; +2CA5;COPTIC SMALL LETTER SIMA;Ll;0;L;;;;;N;;;2CA4;;2CA4 +2CA6;COPTIC CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;2CA7; +2CA7;COPTIC SMALL LETTER TAU;Ll;0;L;;;;;N;;;2CA6;;2CA6 +2CA8;COPTIC CAPITAL LETTER UA;Lu;0;L;;;;;N;;;;2CA9; +2CA9;COPTIC SMALL LETTER UA;Ll;0;L;;;;;N;;;2CA8;;2CA8 +2CAA;COPTIC CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;2CAB; +2CAB;COPTIC SMALL LETTER FI;Ll;0;L;;;;;N;;;2CAA;;2CAA +2CAC;COPTIC CAPITAL LETTER KHI;Lu;0;L;;;;;N;;;;2CAD; +2CAD;COPTIC SMALL LETTER KHI;Ll;0;L;;;;;N;;;2CAC;;2CAC +2CAE;COPTIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;2CAF; +2CAF;COPTIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;2CAE;;2CAE +2CB0;COPTIC CAPITAL LETTER OOU;Lu;0;L;;;;;N;;;;2CB1; +2CB1;COPTIC SMALL LETTER OOU;Ll;0;L;;;;;N;;;2CB0;;2CB0 +2CB2;COPTIC CAPITAL LETTER DIALECT-P ALEF;Lu;0;L;;;;;N;;;;2CB3; +2CB3;COPTIC SMALL LETTER DIALECT-P ALEF;Ll;0;L;;;;;N;;;2CB2;;2CB2 +2CB4;COPTIC CAPITAL LETTER OLD COPTIC AIN;Lu;0;L;;;;;N;;;;2CB5; +2CB5;COPTIC SMALL LETTER OLD COPTIC AIN;Ll;0;L;;;;;N;;;2CB4;;2CB4 +2CB6;COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE;Lu;0;L;;;;;N;;;;2CB7; +2CB7;COPTIC SMALL LETTER CRYPTOGRAMMIC EIE;Ll;0;L;;;;;N;;;2CB6;;2CB6 +2CB8;COPTIC CAPITAL LETTER DIALECT-P KAPA;Lu;0;L;;;;;N;;;;2CB9; +2CB9;COPTIC SMALL LETTER DIALECT-P KAPA;Ll;0;L;;;;;N;;;2CB8;;2CB8 +2CBA;COPTIC CAPITAL LETTER DIALECT-P NI;Lu;0;L;;;;;N;;;;2CBB; +2CBB;COPTIC SMALL LETTER DIALECT-P NI;Ll;0;L;;;;;N;;;2CBA;;2CBA +2CBC;COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI;Lu;0;L;;;;;N;;;;2CBD; +2CBD;COPTIC SMALL LETTER CRYPTOGRAMMIC NI;Ll;0;L;;;;;N;;;2CBC;;2CBC +2CBE;COPTIC CAPITAL LETTER OLD COPTIC OOU;Lu;0;L;;;;;N;;;;2CBF; +2CBF;COPTIC SMALL LETTER OLD COPTIC OOU;Ll;0;L;;;;;N;;;2CBE;;2CBE +2CC0;COPTIC CAPITAL LETTER SAMPI;Lu;0;L;;;;;N;;;;2CC1; +2CC1;COPTIC SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;2CC0;;2CC0 +2CC2;COPTIC CAPITAL LETTER CROSSED SHEI;Lu;0;L;;;;;N;;;;2CC3; +2CC3;COPTIC SMALL LETTER CROSSED SHEI;Ll;0;L;;;;;N;;;2CC2;;2CC2 +2CC4;COPTIC CAPITAL LETTER OLD COPTIC SHEI;Lu;0;L;;;;;N;;;;2CC5; +2CC5;COPTIC SMALL LETTER OLD COPTIC SHEI;Ll;0;L;;;;;N;;;2CC4;;2CC4 +2CC6;COPTIC CAPITAL LETTER OLD COPTIC ESH;Lu;0;L;;;;;N;;;;2CC7; +2CC7;COPTIC SMALL LETTER OLD COPTIC ESH;Ll;0;L;;;;;N;;;2CC6;;2CC6 +2CC8;COPTIC CAPITAL LETTER AKHMIMIC KHEI;Lu;0;L;;;;;N;;;;2CC9; +2CC9;COPTIC SMALL LETTER AKHMIMIC KHEI;Ll;0;L;;;;;N;;;2CC8;;2CC8 +2CCA;COPTIC CAPITAL LETTER DIALECT-P HORI;Lu;0;L;;;;;N;;;;2CCB; +2CCB;COPTIC SMALL LETTER DIALECT-P HORI;Ll;0;L;;;;;N;;;2CCA;;2CCA +2CCC;COPTIC CAPITAL LETTER OLD COPTIC HORI;Lu;0;L;;;;;N;;;;2CCD; +2CCD;COPTIC SMALL LETTER OLD COPTIC HORI;Ll;0;L;;;;;N;;;2CCC;;2CCC +2CCE;COPTIC CAPITAL LETTER OLD COPTIC HA;Lu;0;L;;;;;N;;;;2CCF; +2CCF;COPTIC SMALL LETTER OLD COPTIC HA;Ll;0;L;;;;;N;;;2CCE;;2CCE +2CD0;COPTIC CAPITAL LETTER L-SHAPED HA;Lu;0;L;;;;;N;;;;2CD1; +2CD1;COPTIC SMALL LETTER L-SHAPED HA;Ll;0;L;;;;;N;;;2CD0;;2CD0 +2CD2;COPTIC CAPITAL LETTER OLD COPTIC HEI;Lu;0;L;;;;;N;;;;2CD3; +2CD3;COPTIC SMALL LETTER OLD COPTIC HEI;Ll;0;L;;;;;N;;;2CD2;;2CD2 +2CD4;COPTIC CAPITAL LETTER OLD COPTIC HAT;Lu;0;L;;;;;N;;;;2CD5; +2CD5;COPTIC SMALL LETTER OLD COPTIC HAT;Ll;0;L;;;;;N;;;2CD4;;2CD4 +2CD6;COPTIC CAPITAL LETTER OLD COPTIC GANGIA;Lu;0;L;;;;;N;;;;2CD7; +2CD7;COPTIC SMALL LETTER OLD COPTIC GANGIA;Ll;0;L;;;;;N;;;2CD6;;2CD6 +2CD8;COPTIC CAPITAL LETTER OLD COPTIC DJA;Lu;0;L;;;;;N;;;;2CD9; +2CD9;COPTIC SMALL LETTER OLD COPTIC DJA;Ll;0;L;;;;;N;;;2CD8;;2CD8 +2CDA;COPTIC CAPITAL LETTER OLD COPTIC SHIMA;Lu;0;L;;;;;N;;;;2CDB; +2CDB;COPTIC SMALL LETTER OLD COPTIC SHIMA;Ll;0;L;;;;;N;;;2CDA;;2CDA +2CDC;COPTIC CAPITAL LETTER OLD NUBIAN SHIMA;Lu;0;L;;;;;N;;;;2CDD; +2CDD;COPTIC SMALL LETTER OLD NUBIAN SHIMA;Ll;0;L;;;;;N;;;2CDC;;2CDC +2CDE;COPTIC CAPITAL LETTER OLD NUBIAN NGI;Lu;0;L;;;;;N;;;;2CDF; +2CDF;COPTIC SMALL LETTER OLD NUBIAN NGI;Ll;0;L;;;;;N;;;2CDE;;2CDE +2CE0;COPTIC CAPITAL LETTER OLD NUBIAN NYI;Lu;0;L;;;;;N;;;;2CE1; +2CE1;COPTIC SMALL LETTER OLD NUBIAN NYI;Ll;0;L;;;;;N;;;2CE0;;2CE0 +2CE2;COPTIC CAPITAL LETTER OLD NUBIAN WAU;Lu;0;L;;;;;N;;;;2CE3; +2CE3;COPTIC SMALL LETTER OLD NUBIAN WAU;Ll;0;L;;;;;N;;;2CE2;;2CE2 +2CE4;COPTIC SYMBOL KAI;Ll;0;L;;;;;N;;;;; +2CE5;COPTIC SYMBOL MI RO;So;0;ON;;;;;N;;;;; +2CE6;COPTIC SYMBOL PI RO;So;0;ON;;;;;N;;;;; +2CE7;COPTIC SYMBOL STAUROS;So;0;ON;;;;;N;;;;; +2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;; +2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;; +2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;; +2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;; +2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; +2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; +2CFC;COPTIC OLD NUBIAN VERSE DIVIDER;Po;0;ON;;;;;N;;;;; +2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;; +2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;; +2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;; +2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;Khutsuri;10A0;;10A0 +2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;Khutsuri;10A1;;10A1 +2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;Khutsuri;10A2;;10A2 +2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;Khutsuri;10A3;;10A3 +2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;Khutsuri;10A4;;10A4 +2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;Khutsuri;10A5;;10A5 +2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;Khutsuri;10A6;;10A6 +2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;Khutsuri;10A7;;10A7 +2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;Khutsuri;10A8;;10A8 +2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;Khutsuri;10A9;;10A9 +2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;Khutsuri;10AA;;10AA +2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;Khutsuri;10AB;;10AB +2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;Khutsuri;10AC;;10AC +2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;Khutsuri;10AD;;10AD +2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;Khutsuri;10AE;;10AE +2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;Khutsuri;10AF;;10AF +2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;Khutsuri;10B0;;10B0 +2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;Khutsuri;10B1;;10B1 +2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;Khutsuri;10B2;;10B2 +2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;Khutsuri;10B3;;10B3 +2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;Khutsuri;10B4;;10B4 +2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;Khutsuri;10B5;;10B5 +2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;Khutsuri;10B6;;10B6 +2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;Khutsuri;10B7;;10B7 +2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;Khutsuri;10B8;;10B8 +2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;Khutsuri;10B9;;10B9 +2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;Khutsuri;10BA;;10BA +2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;Khutsuri;10BB;;10BB +2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;Khutsuri;10BC;;10BC +2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;Khutsuri;10BD;;10BD +2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;Khutsuri;10BE;;10BE +2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;Khutsuri;10BF;;10BF +2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;Khutsuri;10C0;;10C0 +2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;Khutsuri;10C1;;10C1 +2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;Khutsuri;10C2;;10C2 +2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;Khutsuri;10C3;;10C3 +2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;Khutsuri;10C4;;10C4 +2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;Khutsuri;10C5;;10C5 +2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;; +2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;; +2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;; +2D33;TIFINAGH LETTER YAG;Lo;0;L;;;;;N;;;;; +2D34;TIFINAGH LETTER YAGHH;Lo;0;L;;;;;N;;;;; +2D35;TIFINAGH LETTER BERBER ACADEMY YAJ;Lo;0;L;;;;;N;;;;; +2D36;TIFINAGH LETTER YAJ;Lo;0;L;;;;;N;;;;; +2D37;TIFINAGH LETTER YAD;Lo;0;L;;;;;N;;;;; +2D38;TIFINAGH LETTER YADH;Lo;0;L;;;;;N;;;;; +2D39;TIFINAGH LETTER YADD;Lo;0;L;;;;;N;;;;; +2D3A;TIFINAGH LETTER YADDH;Lo;0;L;;;;;N;;;;; +2D3B;TIFINAGH LETTER YEY;Lo;0;L;;;;;N;;;;; +2D3C;TIFINAGH LETTER YAF;Lo;0;L;;;;;N;;;;; +2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;; +2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;; +2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;; +2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;Tuareg yab;;; +2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;; +2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;; +2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;; +2D44;TIFINAGH LETTER YAA;Lo;0;L;;;;;N;;;;; +2D45;TIFINAGH LETTER YAKH;Lo;0;L;;;;;N;;;;; +2D46;TIFINAGH LETTER TUAREG YAKH;Lo;0;L;;;;;N;;;;; +2D47;TIFINAGH LETTER YAQ;Lo;0;L;;;;;N;;;;; +2D48;TIFINAGH LETTER TUAREG YAQ;Lo;0;L;;;;;N;;;;; +2D49;TIFINAGH LETTER YI;Lo;0;L;;;;;N;;;;; +2D4A;TIFINAGH LETTER YAZH;Lo;0;L;;;;;N;;;;; +2D4B;TIFINAGH LETTER AHAGGAR YAZH;Lo;0;L;;;;;N;;;;; +2D4C;TIFINAGH LETTER TUAREG YAZH;Lo;0;L;;;;;N;;;;; +2D4D;TIFINAGH LETTER YAL;Lo;0;L;;;;;N;;;;; +2D4E;TIFINAGH LETTER YAM;Lo;0;L;;;;;N;;;;; +2D4F;TIFINAGH LETTER YAN;Lo;0;L;;;;;N;;;;; +2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;; +2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;; +2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;; +2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;Tuareg yaw;;; +2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;; +2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;; +2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;; +2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;; +2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;Adrar yaj;;; +2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;; +2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;; +2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;; +2D5C;TIFINAGH LETTER YAT;Lo;0;L;;;;;N;;;;; +2D5D;TIFINAGH LETTER YATH;Lo;0;L;;;;;N;;;;; +2D5E;TIFINAGH LETTER YACH;Lo;0;L;;;;;N;;;;; +2D5F;TIFINAGH LETTER YATT;Lo;0;L;;;;;N;;;;; +2D60;TIFINAGH LETTER YAV;Lo;0;L;;;;;N;;;;; +2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;; +2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;; +2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;; +2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;harpoon yaz;;; +2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;; +2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L; 2D61;;;;N;;tamatart;;; +2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;; +2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;; +2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;; +2D83;ETHIOPIC SYLLABLE SOA;Lo;0;L;;;;;N;;;;; +2D84;ETHIOPIC SYLLABLE SHOA;Lo;0;L;;;;;N;;;;; +2D85;ETHIOPIC SYLLABLE BOA;Lo;0;L;;;;;N;;;;; +2D86;ETHIOPIC SYLLABLE TOA;Lo;0;L;;;;;N;;;;; +2D87;ETHIOPIC SYLLABLE COA;Lo;0;L;;;;;N;;;;; +2D88;ETHIOPIC SYLLABLE NOA;Lo;0;L;;;;;N;;;;; +2D89;ETHIOPIC SYLLABLE NYOA;Lo;0;L;;;;;N;;;;; +2D8A;ETHIOPIC SYLLABLE GLOTTAL OA;Lo;0;L;;;;;N;;;;; +2D8B;ETHIOPIC SYLLABLE ZOA;Lo;0;L;;;;;N;;;;; +2D8C;ETHIOPIC SYLLABLE DOA;Lo;0;L;;;;;N;;;;; +2D8D;ETHIOPIC SYLLABLE DDOA;Lo;0;L;;;;;N;;;;; +2D8E;ETHIOPIC SYLLABLE JOA;Lo;0;L;;;;;N;;;;; +2D8F;ETHIOPIC SYLLABLE THOA;Lo;0;L;;;;;N;;;;; +2D90;ETHIOPIC SYLLABLE CHOA;Lo;0;L;;;;;N;;;;; +2D91;ETHIOPIC SYLLABLE PHOA;Lo;0;L;;;;;N;;;;; +2D92;ETHIOPIC SYLLABLE POA;Lo;0;L;;;;;N;;;;; +2D93;ETHIOPIC SYLLABLE GGWA;Lo;0;L;;;;;N;;;;; +2D94;ETHIOPIC SYLLABLE GGWI;Lo;0;L;;;;;N;;;;; +2D95;ETHIOPIC SYLLABLE GGWEE;Lo;0;L;;;;;N;;;;; +2D96;ETHIOPIC SYLLABLE GGWE;Lo;0;L;;;;;N;;;;; +2DA0;ETHIOPIC SYLLABLE SSA;Lo;0;L;;;;;N;;;;; +2DA1;ETHIOPIC SYLLABLE SSU;Lo;0;L;;;;;N;;;;; +2DA2;ETHIOPIC SYLLABLE SSI;Lo;0;L;;;;;N;;;;; +2DA3;ETHIOPIC SYLLABLE SSAA;Lo;0;L;;;;;N;;;;; +2DA4;ETHIOPIC SYLLABLE SSEE;Lo;0;L;;;;;N;;;;; +2DA5;ETHIOPIC SYLLABLE SSE;Lo;0;L;;;;;N;;;;; +2DA6;ETHIOPIC SYLLABLE SSO;Lo;0;L;;;;;N;;;;; +2DA8;ETHIOPIC SYLLABLE CCA;Lo;0;L;;;;;N;;;;; +2DA9;ETHIOPIC SYLLABLE CCU;Lo;0;L;;;;;N;;;;; +2DAA;ETHIOPIC SYLLABLE CCI;Lo;0;L;;;;;N;;;;; +2DAB;ETHIOPIC SYLLABLE CCAA;Lo;0;L;;;;;N;;;;; +2DAC;ETHIOPIC SYLLABLE CCEE;Lo;0;L;;;;;N;;;;; +2DAD;ETHIOPIC SYLLABLE CCE;Lo;0;L;;;;;N;;;;; +2DAE;ETHIOPIC SYLLABLE CCO;Lo;0;L;;;;;N;;;;; +2DB0;ETHIOPIC SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; +2DB1;ETHIOPIC SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; +2DB2;ETHIOPIC SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; +2DB3;ETHIOPIC SYLLABLE ZZAA;Lo;0;L;;;;;N;;;;; +2DB4;ETHIOPIC SYLLABLE ZZEE;Lo;0;L;;;;;N;;;;; +2DB5;ETHIOPIC SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; +2DB6;ETHIOPIC SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; +2DB8;ETHIOPIC SYLLABLE CCHA;Lo;0;L;;;;;N;;;;; +2DB9;ETHIOPIC SYLLABLE CCHU;Lo;0;L;;;;;N;;;;; +2DBA;ETHIOPIC SYLLABLE CCHI;Lo;0;L;;;;;N;;;;; +2DBB;ETHIOPIC SYLLABLE CCHAA;Lo;0;L;;;;;N;;;;; +2DBC;ETHIOPIC SYLLABLE CCHEE;Lo;0;L;;;;;N;;;;; +2DBD;ETHIOPIC SYLLABLE CCHE;Lo;0;L;;;;;N;;;;; +2DBE;ETHIOPIC SYLLABLE CCHO;Lo;0;L;;;;;N;;;;; +2DC0;ETHIOPIC SYLLABLE QYA;Lo;0;L;;;;;N;;;;; +2DC1;ETHIOPIC SYLLABLE QYU;Lo;0;L;;;;;N;;;;; +2DC2;ETHIOPIC SYLLABLE QYI;Lo;0;L;;;;;N;;;;; +2DC3;ETHIOPIC SYLLABLE QYAA;Lo;0;L;;;;;N;;;;; +2DC4;ETHIOPIC SYLLABLE QYEE;Lo;0;L;;;;;N;;;;; +2DC5;ETHIOPIC SYLLABLE QYE;Lo;0;L;;;;;N;;;;; +2DC6;ETHIOPIC SYLLABLE QYO;Lo;0;L;;;;;N;;;;; +2DC8;ETHIOPIC SYLLABLE KYA;Lo;0;L;;;;;N;;;;; +2DC9;ETHIOPIC SYLLABLE KYU;Lo;0;L;;;;;N;;;;; +2DCA;ETHIOPIC SYLLABLE KYI;Lo;0;L;;;;;N;;;;; +2DCB;ETHIOPIC SYLLABLE KYAA;Lo;0;L;;;;;N;;;;; +2DCC;ETHIOPIC SYLLABLE KYEE;Lo;0;L;;;;;N;;;;; +2DCD;ETHIOPIC SYLLABLE KYE;Lo;0;L;;;;;N;;;;; +2DCE;ETHIOPIC SYLLABLE KYO;Lo;0;L;;;;;N;;;;; +2DD0;ETHIOPIC SYLLABLE XYA;Lo;0;L;;;;;N;;;;; +2DD1;ETHIOPIC SYLLABLE XYU;Lo;0;L;;;;;N;;;;; +2DD2;ETHIOPIC SYLLABLE XYI;Lo;0;L;;;;;N;;;;; +2DD3;ETHIOPIC SYLLABLE XYAA;Lo;0;L;;;;;N;;;;; +2DD4;ETHIOPIC SYLLABLE XYEE;Lo;0;L;;;;;N;;;;; +2DD5;ETHIOPIC SYLLABLE XYE;Lo;0;L;;;;;N;;;;; +2DD6;ETHIOPIC SYLLABLE XYO;Lo;0;L;;;;;N;;;;; +2DD8;ETHIOPIC SYLLABLE GYA;Lo;0;L;;;;;N;;;;; +2DD9;ETHIOPIC SYLLABLE GYU;Lo;0;L;;;;;N;;;;; +2DDA;ETHIOPIC SYLLABLE GYI;Lo;0;L;;;;;N;;;;; +2DDB;ETHIOPIC SYLLABLE GYAA;Lo;0;L;;;;;N;;;;; +2DDC;ETHIOPIC SYLLABLE GYEE;Lo;0;L;;;;;N;;;;; +2DDD;ETHIOPIC SYLLABLE GYE;Lo;0;L;;;;;N;;;;; +2DDE;ETHIOPIC SYLLABLE GYO;Lo;0;L;;;;;N;;;;; +2DE0;COMBINING CYRILLIC LETTER BE;Mn;230;NSM;;;;;N;;;;; +2DE1;COMBINING CYRILLIC LETTER VE;Mn;230;NSM;;;;;N;;;;; +2DE2;COMBINING CYRILLIC LETTER GHE;Mn;230;NSM;;;;;N;;;;; +2DE3;COMBINING CYRILLIC LETTER DE;Mn;230;NSM;;;;;N;;;;; +2DE4;COMBINING CYRILLIC LETTER ZHE;Mn;230;NSM;;;;;N;;;;; +2DE5;COMBINING CYRILLIC LETTER ZE;Mn;230;NSM;;;;;N;;;;; +2DE6;COMBINING CYRILLIC LETTER KA;Mn;230;NSM;;;;;N;;;;; +2DE7;COMBINING CYRILLIC LETTER EL;Mn;230;NSM;;;;;N;;;;; +2DE8;COMBINING CYRILLIC LETTER EM;Mn;230;NSM;;;;;N;;;;; +2DE9;COMBINING CYRILLIC LETTER EN;Mn;230;NSM;;;;;N;;;;; +2DEA;COMBINING CYRILLIC LETTER O;Mn;230;NSM;;;;;N;;;;; +2DEB;COMBINING CYRILLIC LETTER PE;Mn;230;NSM;;;;;N;;;;; +2DEC;COMBINING CYRILLIC LETTER ER;Mn;230;NSM;;;;;N;;;;; +2DED;COMBINING CYRILLIC LETTER ES;Mn;230;NSM;;;;;N;;;;; +2DEE;COMBINING CYRILLIC LETTER TE;Mn;230;NSM;;;;;N;;;;; +2DEF;COMBINING CYRILLIC LETTER HA;Mn;230;NSM;;;;;N;;;;; +2DF0;COMBINING CYRILLIC LETTER TSE;Mn;230;NSM;;;;;N;;;;; +2DF1;COMBINING CYRILLIC LETTER CHE;Mn;230;NSM;;;;;N;;;;; +2DF2;COMBINING CYRILLIC LETTER SHA;Mn;230;NSM;;;;;N;;;;; +2DF3;COMBINING CYRILLIC LETTER SHCHA;Mn;230;NSM;;;;;N;;;;; +2DF4;COMBINING CYRILLIC LETTER FITA;Mn;230;NSM;;;;;N;;;;; +2DF5;COMBINING CYRILLIC LETTER ES-TE;Mn;230;NSM;;;;;N;;;;; +2DF6;COMBINING CYRILLIC LETTER A;Mn;230;NSM;;;;;N;;;;; +2DF7;COMBINING CYRILLIC LETTER IE;Mn;230;NSM;;;;;N;;;;; +2DF8;COMBINING CYRILLIC LETTER DJERV;Mn;230;NSM;;;;;N;;;;; +2DF9;COMBINING CYRILLIC LETTER MONOGRAPH UK;Mn;230;NSM;;;;;N;;;;; +2DFA;COMBINING CYRILLIC LETTER YAT;Mn;230;NSM;;;;;N;;;;; +2DFB;COMBINING CYRILLIC LETTER YU;Mn;230;NSM;;;;;N;;;;; +2DFC;COMBINING CYRILLIC LETTER IOTIFIED A;Mn;230;NSM;;;;;N;;;;; +2DFD;COMBINING CYRILLIC LETTER LITTLE YUS;Mn;230;NSM;;;;;N;;;;; +2DFE;COMBINING CYRILLIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;; +2DFF;COMBINING CYRILLIC LETTER IOTIFIED BIG YUS;Mn;230;NSM;;;;;N;;;;; +2E00;RIGHT ANGLE SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;; +2E01;RIGHT ANGLE DOTTED SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;; +2E02;LEFT SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E03;RIGHT SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E06;RAISED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;; +2E07;RAISED DOTTED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;; +2E08;DOTTED TRANSPOSITION MARKER;Po;0;ON;;;;;N;;;;; +2E09;LEFT TRANSPOSITION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E0A;RIGHT TRANSPOSITION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E0B;RAISED SQUARE;Po;0;ON;;;;;N;;;;; +2E0C;LEFT RAISED OMISSION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E0D;RIGHT RAISED OMISSION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E0E;EDITORIAL CORONIS;Po;0;ON;;;;;N;;;;; +2E0F;PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E10;FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E11;REVERSED FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E12;HYPODIASTOLE;Po;0;ON;;;;;N;;;;; +2E13;DOTTED OBELOS;Po;0;ON;;;;;N;;;;; +2E14;DOWNWARDS ANCORA;Po;0;ON;;;;;N;;;;; +2E15;UPWARDS ANCORA;Po;0;ON;;;;;N;;;;; +2E16;DOTTED RIGHT-POINTING ANGLE;Po;0;ON;;;;;N;;;;; +2E17;DOUBLE OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;; +2E18;INVERTED INTERROBANG;Po;0;ON;;;;;N;;;;; +2E19;PALM BRANCH;Po;0;ON;;;;;N;;;;; +2E1A;HYPHEN WITH DIAERESIS;Pd;0;ON;;;;;N;;;;; +2E1B;TILDE WITH RING ABOVE;Po;0;ON;;;;;N;;;;; +2E1C;LEFT LOW PARAPHRASE BRACKET;Pi;0;ON;;;;;Y;;;;; +2E1D;RIGHT LOW PARAPHRASE BRACKET;Pf;0;ON;;;;;Y;;;;; +2E1E;TILDE WITH DOT ABOVE;Po;0;ON;;;;;N;;;;; +2E1F;TILDE WITH DOT BELOW;Po;0;ON;;;;;N;;;;; +2E20;LEFT VERTICAL BAR WITH QUILL;Pi;0;ON;;;;;Y;;;;; +2E21;RIGHT VERTICAL BAR WITH QUILL;Pf;0;ON;;;;;Y;;;;; +2E22;TOP LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;; +2E23;TOP RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;; +2E24;BOTTOM LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;; +2E25;BOTTOM RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;; +2E26;LEFT SIDEWAYS U BRACKET;Ps;0;ON;;;;;Y;;;;; +2E27;RIGHT SIDEWAYS U BRACKET;Pe;0;ON;;;;;Y;;;;; +2E28;LEFT DOUBLE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2E29;RIGHT DOUBLE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2E2A;TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2B;ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2C;SQUARED FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2D;FIVE DOT MARK;Po;0;ON;;;;;N;;;;; +2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;; +2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;; +2E30;RING POINT;Po;0;ON;;;;;N;;;;; +2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; +2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; +2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; +2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;; +2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;; +2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;; +2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;; +2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;; +2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;; +2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;; +2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;; +2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;; +2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;; +2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;; +2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;; +2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;; +2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;; +2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;; +2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;; +2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;; +2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;; +2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;; +2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;; +2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;; +2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;; +2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;; +2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;; +2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;; +2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;; +2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;; +2E9F;CJK RADICAL MOTHER;So;0;ON; 6BCD;;;;N;;;;; +2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;; +2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;; +2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;; +2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;; +2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;; +2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;; +2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;; +2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;; +2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;; +2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;; +2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;; +2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;; +2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;; +2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;; +2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;; +2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;; +2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;; +2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;; +2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;; +2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;; +2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;; +2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;; +2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;; +2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;; +2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;; +2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;; +2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;; +2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;; +2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;; +2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;; +2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;; +2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;; +2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;; +2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;; +2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;; +2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;; +2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;; +2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;; +2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;; +2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;; +2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;; +2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;; +2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;; +2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;; +2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;; +2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;; +2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;; +2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;; +2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;; +2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;; +2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;; +2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;; +2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;; +2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;; +2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;; +2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;; +2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;; +2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;; +2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;; +2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;; +2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;; +2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;; +2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;; +2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;; +2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;; +2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;; +2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;; +2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;; +2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;; +2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;; +2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;; +2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;; +2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;; +2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;; +2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;; +2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;; +2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;; +2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON; 9F9F;;;;N;;;;; +2F00;KANGXI RADICAL ONE;So;0;ON; 4E00;;;;N;;;;; +2F01;KANGXI RADICAL LINE;So;0;ON; 4E28;;;;N;;;;; +2F02;KANGXI RADICAL DOT;So;0;ON; 4E36;;;;N;;;;; +2F03;KANGXI RADICAL SLASH;So;0;ON; 4E3F;;;;N;;;;; +2F04;KANGXI RADICAL SECOND;So;0;ON; 4E59;;;;N;;;;; +2F05;KANGXI RADICAL HOOK;So;0;ON; 4E85;;;;N;;;;; +2F06;KANGXI RADICAL TWO;So;0;ON; 4E8C;;;;N;;;;; +2F07;KANGXI RADICAL LID;So;0;ON; 4EA0;;;;N;;;;; +2F08;KANGXI RADICAL MAN;So;0;ON; 4EBA;;;;N;;;;; +2F09;KANGXI RADICAL LEGS;So;0;ON; 513F;;;;N;;;;; +2F0A;KANGXI RADICAL ENTER;So;0;ON; 5165;;;;N;;;;; +2F0B;KANGXI RADICAL EIGHT;So;0;ON; 516B;;;;N;;;;; +2F0C;KANGXI RADICAL DOWN BOX;So;0;ON; 5182;;;;N;;;;; +2F0D;KANGXI RADICAL COVER;So;0;ON; 5196;;;;N;;;;; +2F0E;KANGXI RADICAL ICE;So;0;ON; 51AB;;;;N;;;;; +2F0F;KANGXI RADICAL TABLE;So;0;ON; 51E0;;;;N;;;;; +2F10;KANGXI RADICAL OPEN BOX;So;0;ON; 51F5;;;;N;;;;; +2F11;KANGXI RADICAL KNIFE;So;0;ON; 5200;;;;N;;;;; +2F12;KANGXI RADICAL POWER;So;0;ON; 529B;;;;N;;;;; +2F13;KANGXI RADICAL WRAP;So;0;ON; 52F9;;;;N;;;;; +2F14;KANGXI RADICAL SPOON;So;0;ON; 5315;;;;N;;;;; +2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON; 531A;;;;N;;;;; +2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON; 5338;;;;N;;;;; +2F17;KANGXI RADICAL TEN;So;0;ON; 5341;;;;N;;;;; +2F18;KANGXI RADICAL DIVINATION;So;0;ON; 535C;;;;N;;;;; +2F19;KANGXI RADICAL SEAL;So;0;ON; 5369;;;;N;;;;; +2F1A;KANGXI RADICAL CLIFF;So;0;ON; 5382;;;;N;;;;; +2F1B;KANGXI RADICAL PRIVATE;So;0;ON; 53B6;;;;N;;;;; +2F1C;KANGXI RADICAL AGAIN;So;0;ON; 53C8;;;;N;;;;; +2F1D;KANGXI RADICAL MOUTH;So;0;ON; 53E3;;;;N;;;;; +2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON; 56D7;;;;N;;;;; +2F1F;KANGXI RADICAL EARTH;So;0;ON; 571F;;;;N;;;;; +2F20;KANGXI RADICAL SCHOLAR;So;0;ON; 58EB;;;;N;;;;; +2F21;KANGXI RADICAL GO;So;0;ON; 5902;;;;N;;;;; +2F22;KANGXI RADICAL GO SLOWLY;So;0;ON; 590A;;;;N;;;;; +2F23;KANGXI RADICAL EVENING;So;0;ON; 5915;;;;N;;;;; +2F24;KANGXI RADICAL BIG;So;0;ON; 5927;;;;N;;;;; +2F25;KANGXI RADICAL WOMAN;So;0;ON; 5973;;;;N;;;;; +2F26;KANGXI RADICAL CHILD;So;0;ON; 5B50;;;;N;;;;; +2F27;KANGXI RADICAL ROOF;So;0;ON; 5B80;;;;N;;;;; +2F28;KANGXI RADICAL INCH;So;0;ON; 5BF8;;;;N;;;;; +2F29;KANGXI RADICAL SMALL;So;0;ON; 5C0F;;;;N;;;;; +2F2A;KANGXI RADICAL LAME;So;0;ON; 5C22;;;;N;;;;; +2F2B;KANGXI RADICAL CORPSE;So;0;ON; 5C38;;;;N;;;;; +2F2C;KANGXI RADICAL SPROUT;So;0;ON; 5C6E;;;;N;;;;; +2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON; 5C71;;;;N;;;;; +2F2E;KANGXI RADICAL RIVER;So;0;ON; 5DDB;;;;N;;;;; +2F2F;KANGXI RADICAL WORK;So;0;ON; 5DE5;;;;N;;;;; +2F30;KANGXI RADICAL ONESELF;So;0;ON; 5DF1;;;;N;;;;; +2F31;KANGXI RADICAL TURBAN;So;0;ON; 5DFE;;;;N;;;;; +2F32;KANGXI RADICAL DRY;So;0;ON; 5E72;;;;N;;;;; +2F33;KANGXI RADICAL SHORT THREAD;So;0;ON; 5E7A;;;;N;;;;; +2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON; 5E7F;;;;N;;;;; +2F35;KANGXI RADICAL LONG STRIDE;So;0;ON; 5EF4;;;;N;;;;; +2F36;KANGXI RADICAL TWO HANDS;So;0;ON; 5EFE;;;;N;;;;; +2F37;KANGXI RADICAL SHOOT;So;0;ON; 5F0B;;;;N;;;;; +2F38;KANGXI RADICAL BOW;So;0;ON; 5F13;;;;N;;;;; +2F39;KANGXI RADICAL SNOUT;So;0;ON; 5F50;;;;N;;;;; +2F3A;KANGXI RADICAL BRISTLE;So;0;ON; 5F61;;;;N;;;;; +2F3B;KANGXI RADICAL STEP;So;0;ON; 5F73;;;;N;;;;; +2F3C;KANGXI RADICAL HEART;So;0;ON; 5FC3;;;;N;;;;; +2F3D;KANGXI RADICAL HALBERD;So;0;ON; 6208;;;;N;;;;; +2F3E;KANGXI RADICAL DOOR;So;0;ON; 6236;;;;N;;;;; +2F3F;KANGXI RADICAL HAND;So;0;ON; 624B;;;;N;;;;; +2F40;KANGXI RADICAL BRANCH;So;0;ON; 652F;;;;N;;;;; +2F41;KANGXI RADICAL RAP;So;0;ON; 6534;;;;N;;;;; +2F42;KANGXI RADICAL SCRIPT;So;0;ON; 6587;;;;N;;;;; +2F43;KANGXI RADICAL DIPPER;So;0;ON; 6597;;;;N;;;;; +2F44;KANGXI RADICAL AXE;So;0;ON; 65A4;;;;N;;;;; +2F45;KANGXI RADICAL SQUARE;So;0;ON; 65B9;;;;N;;;;; +2F46;KANGXI RADICAL NOT;So;0;ON; 65E0;;;;N;;;;; +2F47;KANGXI RADICAL SUN;So;0;ON; 65E5;;;;N;;;;; +2F48;KANGXI RADICAL SAY;So;0;ON; 66F0;;;;N;;;;; +2F49;KANGXI RADICAL MOON;So;0;ON; 6708;;;;N;;;;; +2F4A;KANGXI RADICAL TREE;So;0;ON; 6728;;;;N;;;;; +2F4B;KANGXI RADICAL LACK;So;0;ON; 6B20;;;;N;;;;; +2F4C;KANGXI RADICAL STOP;So;0;ON; 6B62;;;;N;;;;; +2F4D;KANGXI RADICAL DEATH;So;0;ON; 6B79;;;;N;;;;; +2F4E;KANGXI RADICAL WEAPON;So;0;ON; 6BB3;;;;N;;;;; +2F4F;KANGXI RADICAL DO NOT;So;0;ON; 6BCB;;;;N;;;;; +2F50;KANGXI RADICAL COMPARE;So;0;ON; 6BD4;;;;N;;;;; +2F51;KANGXI RADICAL FUR;So;0;ON; 6BDB;;;;N;;;;; +2F52;KANGXI RADICAL CLAN;So;0;ON; 6C0F;;;;N;;;;; +2F53;KANGXI RADICAL STEAM;So;0;ON; 6C14;;;;N;;;;; +2F54;KANGXI RADICAL WATER;So;0;ON; 6C34;;;;N;;;;; +2F55;KANGXI RADICAL FIRE;So;0;ON; 706B;;;;N;;;;; +2F56;KANGXI RADICAL CLAW;So;0;ON; 722A;;;;N;;;;; +2F57;KANGXI RADICAL FATHER;So;0;ON; 7236;;;;N;;;;; +2F58;KANGXI RADICAL DOUBLE X;So;0;ON; 723B;;;;N;;;;; +2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON; 723F;;;;N;;;;; +2F5A;KANGXI RADICAL SLICE;So;0;ON; 7247;;;;N;;;;; +2F5B;KANGXI RADICAL FANG;So;0;ON; 7259;;;;N;;;;; +2F5C;KANGXI RADICAL COW;So;0;ON; 725B;;;;N;;;;; +2F5D;KANGXI RADICAL DOG;So;0;ON; 72AC;;;;N;;;;; +2F5E;KANGXI RADICAL PROFOUND;So;0;ON; 7384;;;;N;;;;; +2F5F;KANGXI RADICAL JADE;So;0;ON; 7389;;;;N;;;;; +2F60;KANGXI RADICAL MELON;So;0;ON; 74DC;;;;N;;;;; +2F61;KANGXI RADICAL TILE;So;0;ON; 74E6;;;;N;;;;; +2F62;KANGXI RADICAL SWEET;So;0;ON; 7518;;;;N;;;;; +2F63;KANGXI RADICAL LIFE;So;0;ON; 751F;;;;N;;;;; +2F64;KANGXI RADICAL USE;So;0;ON; 7528;;;;N;;;;; +2F65;KANGXI RADICAL FIELD;So;0;ON; 7530;;;;N;;;;; +2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON; 758B;;;;N;;;;; +2F67;KANGXI RADICAL SICKNESS;So;0;ON; 7592;;;;N;;;;; +2F68;KANGXI RADICAL DOTTED TENT;So;0;ON; 7676;;;;N;;;;; +2F69;KANGXI RADICAL WHITE;So;0;ON; 767D;;;;N;;;;; +2F6A;KANGXI RADICAL SKIN;So;0;ON; 76AE;;;;N;;;;; +2F6B;KANGXI RADICAL DISH;So;0;ON; 76BF;;;;N;;;;; +2F6C;KANGXI RADICAL EYE;So;0;ON; 76EE;;;;N;;;;; +2F6D;KANGXI RADICAL SPEAR;So;0;ON; 77DB;;;;N;;;;; +2F6E;KANGXI RADICAL ARROW;So;0;ON; 77E2;;;;N;;;;; +2F6F;KANGXI RADICAL STONE;So;0;ON; 77F3;;;;N;;;;; +2F70;KANGXI RADICAL SPIRIT;So;0;ON; 793A;;;;N;;;;; +2F71;KANGXI RADICAL TRACK;So;0;ON; 79B8;;;;N;;;;; +2F72;KANGXI RADICAL GRAIN;So;0;ON; 79BE;;;;N;;;;; +2F73;KANGXI RADICAL CAVE;So;0;ON; 7A74;;;;N;;;;; +2F74;KANGXI RADICAL STAND;So;0;ON; 7ACB;;;;N;;;;; +2F75;KANGXI RADICAL BAMBOO;So;0;ON; 7AF9;;;;N;;;;; +2F76;KANGXI RADICAL RICE;So;0;ON; 7C73;;;;N;;;;; +2F77;KANGXI RADICAL SILK;So;0;ON; 7CF8;;;;N;;;;; +2F78;KANGXI RADICAL JAR;So;0;ON; 7F36;;;;N;;;;; +2F79;KANGXI RADICAL NET;So;0;ON; 7F51;;;;N;;;;; +2F7A;KANGXI RADICAL SHEEP;So;0;ON; 7F8A;;;;N;;;;; +2F7B;KANGXI RADICAL FEATHER;So;0;ON; 7FBD;;;;N;;;;; +2F7C;KANGXI RADICAL OLD;So;0;ON; 8001;;;;N;;;;; +2F7D;KANGXI RADICAL AND;So;0;ON; 800C;;;;N;;;;; +2F7E;KANGXI RADICAL PLOW;So;0;ON; 8012;;;;N;;;;; +2F7F;KANGXI RADICAL EAR;So;0;ON; 8033;;;;N;;;;; +2F80;KANGXI RADICAL BRUSH;So;0;ON; 807F;;;;N;;;;; +2F81;KANGXI RADICAL MEAT;So;0;ON; 8089;;;;N;;;;; +2F82;KANGXI RADICAL MINISTER;So;0;ON; 81E3;;;;N;;;;; +2F83;KANGXI RADICAL SELF;So;0;ON; 81EA;;;;N;;;;; +2F84;KANGXI RADICAL ARRIVE;So;0;ON; 81F3;;;;N;;;;; +2F85;KANGXI RADICAL MORTAR;So;0;ON; 81FC;;;;N;;;;; +2F86;KANGXI RADICAL TONGUE;So;0;ON; 820C;;;;N;;;;; +2F87;KANGXI RADICAL OPPOSE;So;0;ON; 821B;;;;N;;;;; +2F88;KANGXI RADICAL BOAT;So;0;ON; 821F;;;;N;;;;; +2F89;KANGXI RADICAL STOPPING;So;0;ON; 826E;;;;N;;;;; +2F8A;KANGXI RADICAL COLOR;So;0;ON; 8272;;;;N;;;;; +2F8B;KANGXI RADICAL GRASS;So;0;ON; 8278;;;;N;;;;; +2F8C;KANGXI RADICAL TIGER;So;0;ON; 864D;;;;N;;;;; +2F8D;KANGXI RADICAL INSECT;So;0;ON; 866B;;;;N;;;;; +2F8E;KANGXI RADICAL BLOOD;So;0;ON; 8840;;;;N;;;;; +2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON; 884C;;;;N;;;;; +2F90;KANGXI RADICAL CLOTHES;So;0;ON; 8863;;;;N;;;;; +2F91;KANGXI RADICAL WEST;So;0;ON; 897E;;;;N;;;;; +2F92;KANGXI RADICAL SEE;So;0;ON; 898B;;;;N;;;;; +2F93;KANGXI RADICAL HORN;So;0;ON; 89D2;;;;N;;;;; +2F94;KANGXI RADICAL SPEECH;So;0;ON; 8A00;;;;N;;;;; +2F95;KANGXI RADICAL VALLEY;So;0;ON; 8C37;;;;N;;;;; +2F96;KANGXI RADICAL BEAN;So;0;ON; 8C46;;;;N;;;;; +2F97;KANGXI RADICAL PIG;So;0;ON; 8C55;;;;N;;;;; +2F98;KANGXI RADICAL BADGER;So;0;ON; 8C78;;;;N;;;;; +2F99;KANGXI RADICAL SHELL;So;0;ON; 8C9D;;;;N;;;;; +2F9A;KANGXI RADICAL RED;So;0;ON; 8D64;;;;N;;;;; +2F9B;KANGXI RADICAL RUN;So;0;ON; 8D70;;;;N;;;;; +2F9C;KANGXI RADICAL FOOT;So;0;ON; 8DB3;;;;N;;;;; +2F9D;KANGXI RADICAL BODY;So;0;ON; 8EAB;;;;N;;;;; +2F9E;KANGXI RADICAL CART;So;0;ON; 8ECA;;;;N;;;;; +2F9F;KANGXI RADICAL BITTER;So;0;ON; 8F9B;;;;N;;;;; +2FA0;KANGXI RADICAL MORNING;So;0;ON; 8FB0;;;;N;;;;; +2FA1;KANGXI RADICAL WALK;So;0;ON; 8FB5;;;;N;;;;; +2FA2;KANGXI RADICAL CITY;So;0;ON; 9091;;;;N;;;;; +2FA3;KANGXI RADICAL WINE;So;0;ON; 9149;;;;N;;;;; +2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON; 91C6;;;;N;;;;; +2FA5;KANGXI RADICAL VILLAGE;So;0;ON; 91CC;;;;N;;;;; +2FA6;KANGXI RADICAL GOLD;So;0;ON; 91D1;;;;N;;;;; +2FA7;KANGXI RADICAL LONG;So;0;ON; 9577;;;;N;;;;; +2FA8;KANGXI RADICAL GATE;So;0;ON; 9580;;;;N;;;;; +2FA9;KANGXI RADICAL MOUND;So;0;ON; 961C;;;;N;;;;; +2FAA;KANGXI RADICAL SLAVE;So;0;ON; 96B6;;;;N;;;;; +2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON; 96B9;;;;N;;;;; +2FAC;KANGXI RADICAL RAIN;So;0;ON; 96E8;;;;N;;;;; +2FAD;KANGXI RADICAL BLUE;So;0;ON; 9751;;;;N;;;;; +2FAE;KANGXI RADICAL WRONG;So;0;ON; 975E;;;;N;;;;; +2FAF;KANGXI RADICAL FACE;So;0;ON; 9762;;;;N;;;;; +2FB0;KANGXI RADICAL LEATHER;So;0;ON; 9769;;;;N;;;;; +2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON; 97CB;;;;N;;;;; +2FB2;KANGXI RADICAL LEEK;So;0;ON; 97ED;;;;N;;;;; +2FB3;KANGXI RADICAL SOUND;So;0;ON; 97F3;;;;N;;;;; +2FB4;KANGXI RADICAL LEAF;So;0;ON; 9801;;;;N;;;;; +2FB5;KANGXI RADICAL WIND;So;0;ON; 98A8;;;;N;;;;; +2FB6;KANGXI RADICAL FLY;So;0;ON; 98DB;;;;N;;;;; +2FB7;KANGXI RADICAL EAT;So;0;ON; 98DF;;;;N;;;;; +2FB8;KANGXI RADICAL HEAD;So;0;ON; 9996;;;;N;;;;; +2FB9;KANGXI RADICAL FRAGRANT;So;0;ON; 9999;;;;N;;;;; +2FBA;KANGXI RADICAL HORSE;So;0;ON; 99AC;;;;N;;;;; +2FBB;KANGXI RADICAL BONE;So;0;ON; 9AA8;;;;N;;;;; +2FBC;KANGXI RADICAL TALL;So;0;ON; 9AD8;;;;N;;;;; +2FBD;KANGXI RADICAL HAIR;So;0;ON; 9ADF;;;;N;;;;; +2FBE;KANGXI RADICAL FIGHT;So;0;ON; 9B25;;;;N;;;;; +2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON; 9B2F;;;;N;;;;; +2FC0;KANGXI RADICAL CAULDRON;So;0;ON; 9B32;;;;N;;;;; +2FC1;KANGXI RADICAL GHOST;So;0;ON; 9B3C;;;;N;;;;; +2FC2;KANGXI RADICAL FISH;So;0;ON; 9B5A;;;;N;;;;; +2FC3;KANGXI RADICAL BIRD;So;0;ON; 9CE5;;;;N;;;;; +2FC4;KANGXI RADICAL SALT;So;0;ON; 9E75;;;;N;;;;; +2FC5;KANGXI RADICAL DEER;So;0;ON; 9E7F;;;;N;;;;; +2FC6;KANGXI RADICAL WHEAT;So;0;ON; 9EA5;;;;N;;;;; +2FC7;KANGXI RADICAL HEMP;So;0;ON; 9EBB;;;;N;;;;; +2FC8;KANGXI RADICAL YELLOW;So;0;ON; 9EC3;;;;N;;;;; +2FC9;KANGXI RADICAL MILLET;So;0;ON; 9ECD;;;;N;;;;; +2FCA;KANGXI RADICAL BLACK;So;0;ON; 9ED1;;;;N;;;;; +2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON; 9EF9;;;;N;;;;; +2FCC;KANGXI RADICAL FROG;So;0;ON; 9EFD;;;;N;;;;; +2FCD;KANGXI RADICAL TRIPOD;So;0;ON; 9F0E;;;;N;;;;; +2FCE;KANGXI RADICAL DRUM;So;0;ON; 9F13;;;;N;;;;; +2FCF;KANGXI RADICAL RAT;So;0;ON; 9F20;;;;N;;;;; +2FD0;KANGXI RADICAL NOSE;So;0;ON; 9F3B;;;;N;;;;; +2FD1;KANGXI RADICAL EVEN;So;0;ON; 9F4A;;;;N;;;;; +2FD2;KANGXI RADICAL TOOTH;So;0;ON; 9F52;;;;N;;;;; +2FD3;KANGXI RADICAL DRAGON;So;0;ON; 9F8D;;;;N;;;;; +2FD4;KANGXI RADICAL TURTLE;So;0;ON; 9F9C;;;;N;;;;; +2FD5;KANGXI RADICAL FLUTE;So;0;ON; 9FA0;;;;N;;;;; +2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;; +2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;; +2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;; +2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;; +2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;; +2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;; +2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;; +2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;; +2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;; +2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;; +2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;; +2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;; +3000;IDEOGRAPHIC SPACE;Zs;0;WS; 0020;;;;N;;;;; +3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;; +3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;; +3003;DITTO MARK;Po;0;ON;;;;;N;;;;; +3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;; +3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;; +3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;; +3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;; +3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;; +300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;; +300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;; +300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;; +300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;; +300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;; +300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;; +3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;; +3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;; +3012;POSTAL MARK;So;0;ON;;;;;N;;;;; +3013;GETA MARK;So;0;ON;;;;;N;;;;; +3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;; +3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;; +3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;; +3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;; +3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;; +3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;; +301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;; +301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;; +301C;WAVE DASH;Pd;0;ON;;;;;N;;;;; +301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;; +301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;; +3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;; +3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;; +3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;; +3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;; +3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;; +3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;; +3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;; +3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;; +3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;; +302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;; +302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;; +302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;; +302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;; +302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; +302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; +3030;WAVY DASH;Pd;0;ON;;;;;N;;;;; +3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;; +3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;; +3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;; +3036;CIRCLED POSTAL MARK;So;0;ON; 3012;;;;N;;;;; +3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;; +3038;HANGZHOU NUMERAL TEN;Nl;0;L; 5341;;;10;N;;;;; +3039;HANGZHOU NUMERAL TWENTY;Nl;0;L; 5344;;;20;N;;;;; +303A;HANGZHOU NUMERAL THIRTY;Nl;0;L; 5345;;;30;N;;;;; +303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +303C;MASU MARK;Lo;0;L;;;;;N;;;;; +303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;; +303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;; +303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;; +3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;; +3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;; +3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;; +3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;; +3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;; +304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;; +304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;; +304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;; +304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;; +304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;; +3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;; +3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;; +3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;; +3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;; +3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;; +3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;; +3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;; +3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;; +3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;; +3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;; +305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;; +305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;; +305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;; +305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;; +305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;; +305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;; +3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;; +3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;; +3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;; +3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;; +3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;; +3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;; +3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;; +3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;; +3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;; +306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;; +306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;; +306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;; +306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;; +306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;; +306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;; +3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;; +3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;; +3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;; +3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;; +3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;; +3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;; +3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;; +3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;; +3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;; +3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;; +307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;; +307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;; +307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;; +307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;; +307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;; +307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;; +3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;; +3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;; +3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;; +3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;; +3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;; +3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;; +3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;; +308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;; +308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;; +308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;; +308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;; +308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;; +3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;; +3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;; +3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;; +3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;; +3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;; +3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;; +309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;; +309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON; 0020 3099;;;;N;;;;; +309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON; 0020 309A;;;;N;;;;; +309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;; +309F;HIRAGANA DIGRAPH YORI;Lo;0;L; 3088 308A;;;;N;;;;; +30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;; +30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;; +30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;; +30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;; +30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;; +30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;; +30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;; +30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;; +30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;; +30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;; +30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;; +30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;; +30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;; +30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;; +30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;; +30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;; +30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;; +30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;; +30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;; +30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;; +30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;; +30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;; +30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;; +30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;; +30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;; +30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;; +30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;; +30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;; +30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;; +30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;; +30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;; +30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;; +30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;; +30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;; +30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;; +30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;; +30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;; +30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;; +30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;; +30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;; +30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;; +30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;; +30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;; +30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;; +30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;; +30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;; +30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;; +30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;; +30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;; +30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;; +30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;; +30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;; +30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;; +30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;; +30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;; +30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;; +30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;; +30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;; +30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;; +30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;; +30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;; +30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;; +30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;; +30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;; +30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;; +30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;; +30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;; +30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;; +30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;; +30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;; +30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;; +30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;; +30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;; +30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;; +30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;; +30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;; +30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;; +30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;; +30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;; +30FB;KATAKANA MIDDLE DOT;Po;0;ON;;;;;N;;;;; +30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;; +30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;; +30FF;KATAKANA DIGRAPH KOTO;Lo;0;L; 30B3 30C8;;;;N;;;;; +3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;; +3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;; +3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;; +3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;; +3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;; +310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;; +310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;; +310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;; +310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;; +310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;; +310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;; +3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;; +3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;; +3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;; +3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;; +3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;; +3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;; +3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;; +3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;; +3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;; +3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;; +311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;; +311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;; +311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;; +311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;; +311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;; +311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;; +3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;; +3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;; +3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;; +3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;; +3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;; +3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;; +3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;; +3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;; +3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;; +3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;; +312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;; +312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;; +312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;; +312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;; +3131;HANGUL LETTER KIYEOK;Lo;0;L; 1100;;;;N;HANGUL LETTER GIYEOG;;;; +3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L; 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;; +3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;; +3134;HANGUL LETTER NIEUN;Lo;0;L; 1102;;;;N;;;;; +3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;; +3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;; +3137;HANGUL LETTER TIKEUT;Lo;0;L; 1103;;;;N;HANGUL LETTER DIGEUD;;;; +3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L; 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;; +3139;HANGUL LETTER RIEUL;Lo;0;L; 1105;;;;N;HANGUL LETTER LIEUL;;;; +313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;; +313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;; +313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;; +313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L; 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;; +313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;; +313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;; +3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;; +3141;HANGUL LETTER MIEUM;Lo;0;L; 1106;;;;N;;;;; +3142;HANGUL LETTER PIEUP;Lo;0;L; 1107;;;;N;HANGUL LETTER BIEUB;;;; +3143;HANGUL LETTER SSANGPIEUP;Lo;0;L; 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;; +3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L; 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;; +3145;HANGUL LETTER SIOS;Lo;0;L; 1109;;;;N;;;;; +3146;HANGUL LETTER SSANGSIOS;Lo;0;L; 110A;;;;N;HANGUL LETTER SSANG SIOS;;;; +3147;HANGUL LETTER IEUNG;Lo;0;L; 110B;;;;N;;;;; +3148;HANGUL LETTER CIEUC;Lo;0;L; 110C;;;;N;HANGUL LETTER JIEUJ;;;; +3149;HANGUL LETTER SSANGCIEUC;Lo;0;L; 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;; +314A;HANGUL LETTER CHIEUCH;Lo;0;L; 110E;;;;N;HANGUL LETTER CIEUC;;;; +314B;HANGUL LETTER KHIEUKH;Lo;0;L; 110F;;;;N;HANGUL LETTER KIYEOK;;;; +314C;HANGUL LETTER THIEUTH;Lo;0;L; 1110;;;;N;HANGUL LETTER TIEUT;;;; +314D;HANGUL LETTER PHIEUPH;Lo;0;L; 1111;;;;N;HANGUL LETTER PIEUP;;;; +314E;HANGUL LETTER HIEUH;Lo;0;L; 1112;;;;N;;;;; +314F;HANGUL LETTER A;Lo;0;L; 1161;;;;N;;;;; +3150;HANGUL LETTER AE;Lo;0;L; 1162;;;;N;;;;; +3151;HANGUL LETTER YA;Lo;0;L; 1163;;;;N;;;;; +3152;HANGUL LETTER YAE;Lo;0;L; 1164;;;;N;;;;; +3153;HANGUL LETTER EO;Lo;0;L; 1165;;;;N;;;;; +3154;HANGUL LETTER E;Lo;0;L; 1166;;;;N;;;;; +3155;HANGUL LETTER YEO;Lo;0;L; 1167;;;;N;;;;; +3156;HANGUL LETTER YE;Lo;0;L; 1168;;;;N;;;;; +3157;HANGUL LETTER O;Lo;0;L; 1169;;;;N;;;;; +3158;HANGUL LETTER WA;Lo;0;L; 116A;;;;N;;;;; +3159;HANGUL LETTER WAE;Lo;0;L; 116B;;;;N;;;;; +315A;HANGUL LETTER OE;Lo;0;L; 116C;;;;N;;;;; +315B;HANGUL LETTER YO;Lo;0;L; 116D;;;;N;;;;; +315C;HANGUL LETTER U;Lo;0;L; 116E;;;;N;;;;; +315D;HANGUL LETTER WEO;Lo;0;L; 116F;;;;N;;;;; +315E;HANGUL LETTER WE;Lo;0;L; 1170;;;;N;;;;; +315F;HANGUL LETTER WI;Lo;0;L; 1171;;;;N;;;;; +3160;HANGUL LETTER YU;Lo;0;L; 1172;;;;N;;;;; +3161;HANGUL LETTER EU;Lo;0;L; 1173;;;;N;;;;; +3162;HANGUL LETTER YI;Lo;0;L; 1174;;;;N;;;;; +3163;HANGUL LETTER I;Lo;0;L; 1175;;;;N;;;;; +3164;HANGUL FILLER;Lo;0;L; 1160;;;;N;HANGUL CAE OM;;;; +3165;HANGUL LETTER SSANGNIEUN;Lo;0;L; 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;; +3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L; 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;; +3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L; 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;; +3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L; 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;; +3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L; 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;; +316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L; 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;; +316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L; 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;; +316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L; 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;; +316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L; 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;; +316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L; 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;; +316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L; 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;; +3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L; 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;; +3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L; 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;; +3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L; 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;; +3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L; 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;; +3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L; 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;; +3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L; 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;; +3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L; 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;; +3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L; 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;; +3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L; 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;; +3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L; 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;; +317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L; 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;; +317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L; 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;; +317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L; 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;; +317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L; 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;; +317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L; 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;; +317F;HANGUL LETTER PANSIOS;Lo;0;L; 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;; +3180;HANGUL LETTER SSANGIEUNG;Lo;0;L; 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;; +3181;HANGUL LETTER YESIEUNG;Lo;0;L; 114C;;;;N;HANGUL LETTER NGIEUNG;;;; +3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L; 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;; +3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L; 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;; +3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L; 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;; +3185;HANGUL LETTER SSANGHIEUH;Lo;0;L; 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;; +3186;HANGUL LETTER YEORINHIEUH;Lo;0;L; 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;; +3187;HANGUL LETTER YO-YA;Lo;0;L; 1184;;;;N;HANGUL LETTER YOYA;;;; +3188;HANGUL LETTER YO-YAE;Lo;0;L; 1185;;;;N;HANGUL LETTER YOYAE;;;; +3189;HANGUL LETTER YO-I;Lo;0;L; 1188;;;;N;HANGUL LETTER YOI;;;; +318A;HANGUL LETTER YU-YEO;Lo;0;L; 1191;;;;N;HANGUL LETTER YUYEO;;;; +318B;HANGUL LETTER YU-YE;Lo;0;L; 1192;;;;N;HANGUL LETTER YUYE;;;; +318C;HANGUL LETTER YU-I;Lo;0;L; 1194;;;;N;HANGUL LETTER YUI;;;; +318D;HANGUL LETTER ARAEA;Lo;0;L; 119E;;;;N;HANGUL LETTER ALAE A;;;; +318E;HANGUL LETTER ARAEAE;Lo;0;L; 11A1;;;;N;HANGUL LETTER ALAE AE;;;; +3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;Kanbun Tateten;;; +3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;Kaeriten;;; +3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L; 4E00;;;1;N;KAERITEN ITI;Kaeriten;;; +3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L; 4E8C;;;2;N;KAERITEN NI;Kaeriten;;; +3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L; 4E09;;;3;N;KAERITEN SAN;Kaeriten;;; +3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L; 56DB;;;4;N;KAERITEN SI;Kaeriten;;; +3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L; 4E0A;;;;N;KAERITEN ZYOU;Kaeriten;;; +3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L; 4E2D;;;;N;KAERITEN TYUU;Kaeriten;;; +3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L; 4E0B;;;;N;KAERITEN GE;Kaeriten;;; +3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L; 7532;;;;N;KAERITEN KOU;Kaeriten;;; +319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L; 4E59;;;;N;KAERITEN OTU;Kaeriten;;; +319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L; 4E19;;;;N;KAERITEN HEI;Kaeriten;;; +319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L; 4E01;;;;N;KAERITEN TEI;Kaeriten;;; +319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L; 5929;;;;N;KAERITEN TEN;Kaeriten;;; +319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L; 5730;;;;N;KAERITEN TI;Kaeriten;;; +319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L; 4EBA;;;;N;KAERITEN ZIN;Kaeriten;;; +31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;; +31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;; +31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;; +31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;; +31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;; +31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;; +31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;; +31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;; +31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;; +31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;; +31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;; +31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;; +31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;; +31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;; +31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;; +31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;; +31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;; +31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;; +31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;; +31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;; +31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;; +31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;; +31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;; +31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;; +31C0;CJK STROKE T;So;0;ON;;;;;N;;;;; +31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;; +31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;; +31C3;CJK STROKE BXG;So;0;ON;;;;;N;;;;; +31C4;CJK STROKE SW;So;0;ON;;;;;N;;;;; +31C5;CJK STROKE HZZ;So;0;ON;;;;;N;;;;; +31C6;CJK STROKE HZG;So;0;ON;;;;;N;;;;; +31C7;CJK STROKE HP;So;0;ON;;;;;N;;;;; +31C8;CJK STROKE HZWG;So;0;ON;;;;;N;;;;; +31C9;CJK STROKE SZWG;So;0;ON;;;;;N;;;;; +31CA;CJK STROKE HZT;So;0;ON;;;;;N;;;;; +31CB;CJK STROKE HZZP;So;0;ON;;;;;N;;;;; +31CC;CJK STROKE HPWG;So;0;ON;;;;;N;;;;; +31CD;CJK STROKE HZW;So;0;ON;;;;;N;;;;; +31CE;CJK STROKE HZZZ;So;0;ON;;;;;N;;;;; +31CF;CJK STROKE N;So;0;ON;;;;;N;;;;; +31D0;CJK STROKE H;So;0;ON;;;;;N;;;;; +31D1;CJK STROKE S;So;0;ON;;;;;N;;;;; +31D2;CJK STROKE P;So;0;ON;;;;;N;;;;; +31D3;CJK STROKE SP;So;0;ON;;;;;N;;;;; +31D4;CJK STROKE D;So;0;ON;;;;;N;;;;; +31D5;CJK STROKE HZ;So;0;ON;;;;;N;;;;; +31D6;CJK STROKE HG;So;0;ON;;;;;N;;;;; +31D7;CJK STROKE SZ;So;0;ON;;;;;N;;;;; +31D8;CJK STROKE SWZ;So;0;ON;;;;;N;;;;; +31D9;CJK STROKE ST;So;0;ON;;;;;N;;;;; +31DA;CJK STROKE SG;So;0;ON;;;;;N;;;;; +31DB;CJK STROKE PD;So;0;ON;;;;;N;;;;; +31DC;CJK STROKE PZ;So;0;ON;;;;;N;;;;; +31DD;CJK STROKE TN;So;0;ON;;;;;N;;;;; +31DE;CJK STROKE SZZ;So;0;ON;;;;;N;;;;; +31DF;CJK STROKE SWG;So;0;ON;;;;;N;;;;; +31E0;CJK STROKE HXWG;So;0;ON;;;;;N;;;;; +31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;; +31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;; +31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;; +31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;; +31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;; +31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;; +31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;; +31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;; +31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;; +31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;; +31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;; +31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;; +31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;; +31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;; +31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;; +31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;; +31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;; +31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;; +31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;; +3200;PARENTHESIZED HANGUL KIYEOK;So;0;L; 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;; +3201;PARENTHESIZED HANGUL NIEUN;So;0;L; 0028 1102 0029;;;;N;;;;; +3202;PARENTHESIZED HANGUL TIKEUT;So;0;L; 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;; +3203;PARENTHESIZED HANGUL RIEUL;So;0;L; 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;; +3204;PARENTHESIZED HANGUL MIEUM;So;0;L; 0028 1106 0029;;;;N;;;;; +3205;PARENTHESIZED HANGUL PIEUP;So;0;L; 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;; +3206;PARENTHESIZED HANGUL SIOS;So;0;L; 0028 1109 0029;;;;N;;;;; +3207;PARENTHESIZED HANGUL IEUNG;So;0;L; 0028 110B 0029;;;;N;;;;; +3208;PARENTHESIZED HANGUL CIEUC;So;0;L; 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;; +3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L; 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;; +320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L; 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;; +320B;PARENTHESIZED HANGUL THIEUTH;So;0;L; 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;; +320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L; 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;; +320D;PARENTHESIZED HANGUL HIEUH;So;0;L; 0028 1112 0029;;;;N;;;;; +320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L; 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;; +320F;PARENTHESIZED HANGUL NIEUN A;So;0;L; 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;; +3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L; 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;; +3211;PARENTHESIZED HANGUL RIEUL A;So;0;L; 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;; +3212;PARENTHESIZED HANGUL MIEUM A;So;0;L; 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;; +3213;PARENTHESIZED HANGUL PIEUP A;So;0;L; 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;; +3214;PARENTHESIZED HANGUL SIOS A;So;0;L; 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;; +3215;PARENTHESIZED HANGUL IEUNG A;So;0;L; 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;; +3216;PARENTHESIZED HANGUL CIEUC A;So;0;L; 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;; +3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L; 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;; +3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L; 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;; +3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L; 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;; +321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L; 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;; +321B;PARENTHESIZED HANGUL HIEUH A;So;0;L; 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;; +321C;PARENTHESIZED HANGUL CIEUC U;So;0;L; 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;; +321D;PARENTHESIZED KOREAN CHARACTER OJEON;So;0;ON; 0028 110B 1169 110C 1165 11AB 0029;;;;N;;;;; +321E;PARENTHESIZED KOREAN CHARACTER O HU;So;0;ON; 0028 110B 1169 1112 116E 0029;;;;N;;;;; +3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L; 0028 4E00 0029;;;1;N;;;;; +3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L; 0028 4E8C 0029;;;2;N;;;;; +3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L; 0028 4E09 0029;;;3;N;;;;; +3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L; 0028 56DB 0029;;;4;N;;;;; +3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L; 0028 4E94 0029;;;5;N;;;;; +3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L; 0028 516D 0029;;;6;N;;;;; +3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L; 0028 4E03 0029;;;7;N;;;;; +3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L; 0028 516B 0029;;;8;N;;;;; +3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L; 0028 4E5D 0029;;;9;N;;;;; +3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L; 0028 5341 0029;;;10;N;;;;; +322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L; 0028 6708 0029;;;;N;;;;; +322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L; 0028 706B 0029;;;;N;;;;; +322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L; 0028 6C34 0029;;;;N;;;;; +322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L; 0028 6728 0029;;;;N;;;;; +322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L; 0028 91D1 0029;;;;N;;;;; +322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L; 0028 571F 0029;;;;N;;;;; +3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L; 0028 65E5 0029;;;;N;;;;; +3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L; 0028 682A 0029;;;;N;;;;; +3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L; 0028 6709 0029;;;;N;;;;; +3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L; 0028 793E 0029;;;;N;;;;; +3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L; 0028 540D 0029;;;;N;;;;; +3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L; 0028 7279 0029;;;;N;;;;; +3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L; 0028 8CA1 0029;;;;N;;;;; +3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L; 0028 795D 0029;;;;N;;;;; +3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L; 0028 52B4 0029;;;;N;;;;; +3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L; 0028 4EE3 0029;;;;N;;;;; +323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L; 0028 547C 0029;;;;N;;;;; +323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L; 0028 5B66 0029;;;;N;;;;; +323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L; 0028 76E3 0029;;;;N;;;;; +323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L; 0028 4F01 0029;;;;N;;;;; +323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L; 0028 8CC7 0029;;;;N;;;;; +323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L; 0028 5354 0029;;;;N;;;;; +3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L; 0028 796D 0029;;;;N;;;;; +3241;PARENTHESIZED IDEOGRAPH REST;So;0;L; 0028 4F11 0029;;;;N;;;;; +3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L; 0028 81EA 0029;;;;N;;;;; +3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L; 0028 81F3 0029;;;;N;;;;; +3250;PARTNERSHIP SIGN;So;0;ON; 0050 0054 0045;;;;N;;;;; +3251;CIRCLED NUMBER TWENTY ONE;No;0;ON; 0032 0031;;;21;N;;;;; +3252;CIRCLED NUMBER TWENTY TWO;No;0;ON; 0032 0032;;;22;N;;;;; +3253;CIRCLED NUMBER TWENTY THREE;No;0;ON; 0032 0033;;;23;N;;;;; +3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON; 0032 0034;;;24;N;;;;; +3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON; 0032 0035;;;25;N;;;;; +3256;CIRCLED NUMBER TWENTY SIX;No;0;ON; 0032 0036;;;26;N;;;;; +3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON; 0032 0037;;;27;N;;;;; +3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON; 0032 0038;;;28;N;;;;; +3259;CIRCLED NUMBER TWENTY NINE;No;0;ON; 0032 0039;;;29;N;;;;; +325A;CIRCLED NUMBER THIRTY;No;0;ON; 0033 0030;;;30;N;;;;; +325B;CIRCLED NUMBER THIRTY ONE;No;0;ON; 0033 0031;;;31;N;;;;; +325C;CIRCLED NUMBER THIRTY TWO;No;0;ON; 0033 0032;;;32;N;;;;; +325D;CIRCLED NUMBER THIRTY THREE;No;0;ON; 0033 0033;;;33;N;;;;; +325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON; 0033 0034;;;34;N;;;;; +325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON; 0033 0035;;;35;N;;;;; +3260;CIRCLED HANGUL KIYEOK;So;0;L; 1100;;;;N;CIRCLED HANGUL GIYEOG;;;; +3261;CIRCLED HANGUL NIEUN;So;0;L; 1102;;;;N;;;;; +3262;CIRCLED HANGUL TIKEUT;So;0;L; 1103;;;;N;CIRCLED HANGUL DIGEUD;;;; +3263;CIRCLED HANGUL RIEUL;So;0;L; 1105;;;;N;CIRCLED HANGUL LIEUL;;;; +3264;CIRCLED HANGUL MIEUM;So;0;L; 1106;;;;N;;;;; +3265;CIRCLED HANGUL PIEUP;So;0;L; 1107;;;;N;CIRCLED HANGUL BIEUB;;;; +3266;CIRCLED HANGUL SIOS;So;0;L; 1109;;;;N;;;;; +3267;CIRCLED HANGUL IEUNG;So;0;L; 110B;;;;N;;;;; +3268;CIRCLED HANGUL CIEUC;So;0;L; 110C;;;;N;CIRCLED HANGUL JIEUJ;;;; +3269;CIRCLED HANGUL CHIEUCH;So;0;L; 110E;;;;N;CIRCLED HANGUL CIEUC;;;; +326A;CIRCLED HANGUL KHIEUKH;So;0;L; 110F;;;;N;CIRCLED HANGUL KIYEOK;;;; +326B;CIRCLED HANGUL THIEUTH;So;0;L; 1110;;;;N;CIRCLED HANGUL TIEUT;;;; +326C;CIRCLED HANGUL PHIEUPH;So;0;L; 1111;;;;N;CIRCLED HANGUL PIEUP;;;; +326D;CIRCLED HANGUL HIEUH;So;0;L; 1112;;;;N;;;;; +326E;CIRCLED HANGUL KIYEOK A;So;0;L; 1100 1161;;;;N;CIRCLED HANGUL GA;;;; +326F;CIRCLED HANGUL NIEUN A;So;0;L; 1102 1161;;;;N;CIRCLED HANGUL NA;;;; +3270;CIRCLED HANGUL TIKEUT A;So;0;L; 1103 1161;;;;N;CIRCLED HANGUL DA;;;; +3271;CIRCLED HANGUL RIEUL A;So;0;L; 1105 1161;;;;N;CIRCLED HANGUL LA;;;; +3272;CIRCLED HANGUL MIEUM A;So;0;L; 1106 1161;;;;N;CIRCLED HANGUL MA;;;; +3273;CIRCLED HANGUL PIEUP A;So;0;L; 1107 1161;;;;N;CIRCLED HANGUL BA;;;; +3274;CIRCLED HANGUL SIOS A;So;0;L; 1109 1161;;;;N;CIRCLED HANGUL SA;;;; +3275;CIRCLED HANGUL IEUNG A;So;0;L; 110B 1161;;;;N;CIRCLED HANGUL A;;;; +3276;CIRCLED HANGUL CIEUC A;So;0;L; 110C 1161;;;;N;CIRCLED HANGUL JA;;;; +3277;CIRCLED HANGUL CHIEUCH A;So;0;L; 110E 1161;;;;N;CIRCLED HANGUL CA;;;; +3278;CIRCLED HANGUL KHIEUKH A;So;0;L; 110F 1161;;;;N;CIRCLED HANGUL KA;;;; +3279;CIRCLED HANGUL THIEUTH A;So;0;L; 1110 1161;;;;N;CIRCLED HANGUL TA;;;; +327A;CIRCLED HANGUL PHIEUPH A;So;0;L; 1111 1161;;;;N;CIRCLED HANGUL PA;;;; +327B;CIRCLED HANGUL HIEUH A;So;0;L; 1112 1161;;;;N;CIRCLED HANGUL HA;;;; +327C;CIRCLED KOREAN CHARACTER CHAMKO;So;0;ON; 110E 1161 11B7 1100 1169;;;;N;;;;; +327D;CIRCLED KOREAN CHARACTER JUEUI;So;0;ON; 110C 116E 110B 1174;;;;N;;;;; +327E;CIRCLED HANGUL IEUNG U;So;0;ON; 110B 116E;;;;N;;;;; +327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;; +3280;CIRCLED IDEOGRAPH ONE;No;0;L; 4E00;;;1;N;;;;; +3281;CIRCLED IDEOGRAPH TWO;No;0;L; 4E8C;;;2;N;;;;; +3282;CIRCLED IDEOGRAPH THREE;No;0;L; 4E09;;;3;N;;;;; +3283;CIRCLED IDEOGRAPH FOUR;No;0;L; 56DB;;;4;N;;;;; +3284;CIRCLED IDEOGRAPH FIVE;No;0;L; 4E94;;;5;N;;;;; +3285;CIRCLED IDEOGRAPH SIX;No;0;L; 516D;;;6;N;;;;; +3286;CIRCLED IDEOGRAPH SEVEN;No;0;L; 4E03;;;7;N;;;;; +3287;CIRCLED IDEOGRAPH EIGHT;No;0;L; 516B;;;8;N;;;;; +3288;CIRCLED IDEOGRAPH NINE;No;0;L; 4E5D;;;9;N;;;;; +3289;CIRCLED IDEOGRAPH TEN;No;0;L; 5341;;;10;N;;;;; +328A;CIRCLED IDEOGRAPH MOON;So;0;L; 6708;;;;N;;;;; +328B;CIRCLED IDEOGRAPH FIRE;So;0;L; 706B;;;;N;;;;; +328C;CIRCLED IDEOGRAPH WATER;So;0;L; 6C34;;;;N;;;;; +328D;CIRCLED IDEOGRAPH WOOD;So;0;L; 6728;;;;N;;;;; +328E;CIRCLED IDEOGRAPH METAL;So;0;L; 91D1;;;;N;;;;; +328F;CIRCLED IDEOGRAPH EARTH;So;0;L; 571F;;;;N;;;;; +3290;CIRCLED IDEOGRAPH SUN;So;0;L; 65E5;;;;N;;;;; +3291;CIRCLED IDEOGRAPH STOCK;So;0;L; 682A;;;;N;;;;; +3292;CIRCLED IDEOGRAPH HAVE;So;0;L; 6709;;;;N;;;;; +3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L; 793E;;;;N;;;;; +3294;CIRCLED IDEOGRAPH NAME;So;0;L; 540D;;;;N;;;;; +3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L; 7279;;;;N;;;;; +3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L; 8CA1;;;;N;;;;; +3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L; 795D;;;;N;;;;; +3298;CIRCLED IDEOGRAPH LABOR;So;0;L; 52B4;;;;N;;;;; +3299;CIRCLED IDEOGRAPH SECRET;So;0;L; 79D8;;;;N;;;;; +329A;CIRCLED IDEOGRAPH MALE;So;0;L; 7537;;;;N;;;;; +329B;CIRCLED IDEOGRAPH FEMALE;So;0;L; 5973;;;;N;;;;; +329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L; 9069;;;;N;;;;; +329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L; 512A;;;;N;;;;; +329E;CIRCLED IDEOGRAPH PRINT;So;0;L; 5370;;;;N;;;;; +329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L; 6CE8;;;;N;;;;; +32A0;CIRCLED IDEOGRAPH ITEM;So;0;L; 9805;;;;N;;;;; +32A1;CIRCLED IDEOGRAPH REST;So;0;L; 4F11;;;;N;;;;; +32A2;CIRCLED IDEOGRAPH COPY;So;0;L; 5199;;;;N;;;;; +32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L; 6B63;;;;N;;;;; +32A4;CIRCLED IDEOGRAPH HIGH;So;0;L; 4E0A;;;;N;;;;; +32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L; 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;; +32A6;CIRCLED IDEOGRAPH LOW;So;0;L; 4E0B;;;;N;;;;; +32A7;CIRCLED IDEOGRAPH LEFT;So;0;L; 5DE6;;;;N;;;;; +32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L; 53F3;;;;N;;;;; +32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L; 533B;;;;N;;;;; +32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L; 5B97;;;;N;;;;; +32AB;CIRCLED IDEOGRAPH STUDY;So;0;L; 5B66;;;;N;;;;; +32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L; 76E3;;;;N;;;;; +32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L; 4F01;;;;N;;;;; +32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L; 8CC7;;;;N;;;;; +32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L; 5354;;;;N;;;;; +32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L; 591C;;;;N;;;;; +32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON; 0033 0036;;;36;N;;;;; +32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON; 0033 0037;;;37;N;;;;; +32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON; 0033 0038;;;38;N;;;;; +32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON; 0033 0039;;;39;N;;;;; +32B5;CIRCLED NUMBER FORTY;No;0;ON; 0034 0030;;;40;N;;;;; +32B6;CIRCLED NUMBER FORTY ONE;No;0;ON; 0034 0031;;;41;N;;;;; +32B7;CIRCLED NUMBER FORTY TWO;No;0;ON; 0034 0032;;;42;N;;;;; +32B8;CIRCLED NUMBER FORTY THREE;No;0;ON; 0034 0033;;;43;N;;;;; +32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON; 0034 0034;;;44;N;;;;; +32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON; 0034 0035;;;45;N;;;;; +32BB;CIRCLED NUMBER FORTY SIX;No;0;ON; 0034 0036;;;46;N;;;;; +32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON; 0034 0037;;;47;N;;;;; +32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON; 0034 0038;;;48;N;;;;; +32BE;CIRCLED NUMBER FORTY NINE;No;0;ON; 0034 0039;;;49;N;;;;; +32BF;CIRCLED NUMBER FIFTY;No;0;ON; 0035 0030;;;50;N;;;;; +32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L; 0031 6708;;;;N;;;;; +32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L; 0032 6708;;;;N;;;;; +32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L; 0033 6708;;;;N;;;;; +32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L; 0034 6708;;;;N;;;;; +32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L; 0035 6708;;;;N;;;;; +32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L; 0036 6708;;;;N;;;;; +32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L; 0037 6708;;;;N;;;;; +32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L; 0038 6708;;;;N;;;;; +32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L; 0039 6708;;;;N;;;;; +32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L; 0031 0030 6708;;;;N;;;;; +32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L; 0031 0031 6708;;;;N;;;;; +32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L; 0031 0032 6708;;;;N;;;;; +32CC;SQUARE HG;So;0;ON; 0048 0067;;;;N;;;;; +32CD;SQUARE ERG;So;0;ON; 0065 0072 0067;;;;N;;;;; +32CE;SQUARE EV;So;0;ON; 0065 0056;;;;N;;;;; +32CF;LIMITED LIABILITY SIGN;So;0;ON; 004C 0054 0044;;;;N;;;;; +32D0;CIRCLED KATAKANA A;So;0;L; 30A2;;;;N;;;;; +32D1;CIRCLED KATAKANA I;So;0;L; 30A4;;;;N;;;;; +32D2;CIRCLED KATAKANA U;So;0;L; 30A6;;;;N;;;;; +32D3;CIRCLED KATAKANA E;So;0;L; 30A8;;;;N;;;;; +32D4;CIRCLED KATAKANA O;So;0;L; 30AA;;;;N;;;;; +32D5;CIRCLED KATAKANA KA;So;0;L; 30AB;;;;N;;;;; +32D6;CIRCLED KATAKANA KI;So;0;L; 30AD;;;;N;;;;; +32D7;CIRCLED KATAKANA KU;So;0;L; 30AF;;;;N;;;;; +32D8;CIRCLED KATAKANA KE;So;0;L; 30B1;;;;N;;;;; +32D9;CIRCLED KATAKANA KO;So;0;L; 30B3;;;;N;;;;; +32DA;CIRCLED KATAKANA SA;So;0;L; 30B5;;;;N;;;;; +32DB;CIRCLED KATAKANA SI;So;0;L; 30B7;;;;N;;;;; +32DC;CIRCLED KATAKANA SU;So;0;L; 30B9;;;;N;;;;; +32DD;CIRCLED KATAKANA SE;So;0;L; 30BB;;;;N;;;;; +32DE;CIRCLED KATAKANA SO;So;0;L; 30BD;;;;N;;;;; +32DF;CIRCLED KATAKANA TA;So;0;L; 30BF;;;;N;;;;; +32E0;CIRCLED KATAKANA TI;So;0;L; 30C1;;;;N;;;;; +32E1;CIRCLED KATAKANA TU;So;0;L; 30C4;;;;N;;;;; +32E2;CIRCLED KATAKANA TE;So;0;L; 30C6;;;;N;;;;; +32E3;CIRCLED KATAKANA TO;So;0;L; 30C8;;;;N;;;;; +32E4;CIRCLED KATAKANA NA;So;0;L; 30CA;;;;N;;;;; +32E5;CIRCLED KATAKANA NI;So;0;L; 30CB;;;;N;;;;; +32E6;CIRCLED KATAKANA NU;So;0;L; 30CC;;;;N;;;;; +32E7;CIRCLED KATAKANA NE;So;0;L; 30CD;;;;N;;;;; +32E8;CIRCLED KATAKANA NO;So;0;L; 30CE;;;;N;;;;; +32E9;CIRCLED KATAKANA HA;So;0;L; 30CF;;;;N;;;;; +32EA;CIRCLED KATAKANA HI;So;0;L; 30D2;;;;N;;;;; +32EB;CIRCLED KATAKANA HU;So;0;L; 30D5;;;;N;;;;; +32EC;CIRCLED KATAKANA HE;So;0;L; 30D8;;;;N;;;;; +32ED;CIRCLED KATAKANA HO;So;0;L; 30DB;;;;N;;;;; +32EE;CIRCLED KATAKANA MA;So;0;L; 30DE;;;;N;;;;; +32EF;CIRCLED KATAKANA MI;So;0;L; 30DF;;;;N;;;;; +32F0;CIRCLED KATAKANA MU;So;0;L; 30E0;;;;N;;;;; +32F1;CIRCLED KATAKANA ME;So;0;L; 30E1;;;;N;;;;; +32F2;CIRCLED KATAKANA MO;So;0;L; 30E2;;;;N;;;;; +32F3;CIRCLED KATAKANA YA;So;0;L; 30E4;;;;N;;;;; +32F4;CIRCLED KATAKANA YU;So;0;L; 30E6;;;;N;;;;; +32F5;CIRCLED KATAKANA YO;So;0;L; 30E8;;;;N;;;;; +32F6;CIRCLED KATAKANA RA;So;0;L; 30E9;;;;N;;;;; +32F7;CIRCLED KATAKANA RI;So;0;L; 30EA;;;;N;;;;; +32F8;CIRCLED KATAKANA RU;So;0;L; 30EB;;;;N;;;;; +32F9;CIRCLED KATAKANA RE;So;0;L; 30EC;;;;N;;;;; +32FA;CIRCLED KATAKANA RO;So;0;L; 30ED;;;;N;;;;; +32FB;CIRCLED KATAKANA WA;So;0;L; 30EF;;;;N;;;;; +32FC;CIRCLED KATAKANA WI;So;0;L; 30F0;;;;N;;;;; +32FD;CIRCLED KATAKANA WE;So;0;L; 30F1;;;;N;;;;; +32FE;CIRCLED KATAKANA WO;So;0;L; 30F2;;;;N;;;;; +3300;SQUARE APAATO;So;0;L; 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;; +3301;SQUARE ARUHUA;So;0;L; 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;; +3302;SQUARE ANPEA;So;0;L; 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;; +3303;SQUARE AARU;So;0;L; 30A2 30FC 30EB;;;;N;SQUARED AARU;;;; +3304;SQUARE ININGU;So;0;L; 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;; +3305;SQUARE INTI;So;0;L; 30A4 30F3 30C1;;;;N;SQUARED INTI;;;; +3306;SQUARE UON;So;0;L; 30A6 30A9 30F3;;;;N;SQUARED UON;;;; +3307;SQUARE ESUKUUDO;So;0;L; 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;; +3308;SQUARE EEKAA;So;0;L; 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;; +3309;SQUARE ONSU;So;0;L; 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;; +330A;SQUARE OOMU;So;0;L; 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;; +330B;SQUARE KAIRI;So;0;L; 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;; +330C;SQUARE KARATTO;So;0;L; 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;; +330D;SQUARE KARORII;So;0;L; 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;; +330E;SQUARE GARON;So;0;L; 30AC 30ED 30F3;;;;N;SQUARED GARON;;;; +330F;SQUARE GANMA;So;0;L; 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;; +3310;SQUARE GIGA;So;0;L; 30AE 30AC;;;;N;SQUARED GIGA;;;; +3311;SQUARE GINII;So;0;L; 30AE 30CB 30FC;;;;N;SQUARED GINII;;;; +3312;SQUARE KYURII;So;0;L; 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;; +3313;SQUARE GIRUDAA;So;0;L; 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;; +3314;SQUARE KIRO;So;0;L; 30AD 30ED;;;;N;SQUARED KIRO;;;; +3315;SQUARE KIROGURAMU;So;0;L; 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;; +3316;SQUARE KIROMEETORU;So;0;L; 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;; +3317;SQUARE KIROWATTO;So;0;L; 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;; +3318;SQUARE GURAMU;So;0;L; 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;; +3319;SQUARE GURAMUTON;So;0;L; 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;; +331A;SQUARE KURUZEIRO;So;0;L; 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;; +331B;SQUARE KUROONE;So;0;L; 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;; +331C;SQUARE KEESU;So;0;L; 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;; +331D;SQUARE KORUNA;So;0;L; 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;; +331E;SQUARE KOOPO;So;0;L; 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;; +331F;SQUARE SAIKURU;So;0;L; 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;; +3320;SQUARE SANTIIMU;So;0;L; 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;; +3321;SQUARE SIRINGU;So;0;L; 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;; +3322;SQUARE SENTI;So;0;L; 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;; +3323;SQUARE SENTO;So;0;L; 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;; +3324;SQUARE DAASU;So;0;L; 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;; +3325;SQUARE DESI;So;0;L; 30C7 30B7;;;;N;SQUARED DESI;;;; +3326;SQUARE DORU;So;0;L; 30C9 30EB;;;;N;SQUARED DORU;;;; +3327;SQUARE TON;So;0;L; 30C8 30F3;;;;N;SQUARED TON;;;; +3328;SQUARE NANO;So;0;L; 30CA 30CE;;;;N;SQUARED NANO;;;; +3329;SQUARE NOTTO;So;0;L; 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;; +332A;SQUARE HAITU;So;0;L; 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;; +332B;SQUARE PAASENTO;So;0;L; 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;; +332C;SQUARE PAATU;So;0;L; 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;; +332D;SQUARE BAARERU;So;0;L; 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;; +332E;SQUARE PIASUTORU;So;0;L; 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;; +332F;SQUARE PIKURU;So;0;L; 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;; +3330;SQUARE PIKO;So;0;L; 30D4 30B3;;;;N;SQUARED PIKO;;;; +3331;SQUARE BIRU;So;0;L; 30D3 30EB;;;;N;SQUARED BIRU;;;; +3332;SQUARE HUARADDO;So;0;L; 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;; +3333;SQUARE HUIITO;So;0;L; 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;; +3334;SQUARE BUSSYERU;So;0;L; 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;; +3335;SQUARE HURAN;So;0;L; 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;; +3336;SQUARE HEKUTAARU;So;0;L; 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;; +3337;SQUARE PESO;So;0;L; 30DA 30BD;;;;N;SQUARED PESO;;;; +3338;SQUARE PENIHI;So;0;L; 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;; +3339;SQUARE HERUTU;So;0;L; 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;; +333A;SQUARE PENSU;So;0;L; 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;; +333B;SQUARE PEEZI;So;0;L; 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;; +333C;SQUARE BEETA;So;0;L; 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;; +333D;SQUARE POINTO;So;0;L; 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;; +333E;SQUARE BORUTO;So;0;L; 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;; +333F;SQUARE HON;So;0;L; 30DB 30F3;;;;N;SQUARED HON;;;; +3340;SQUARE PONDO;So;0;L; 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;; +3341;SQUARE HOORU;So;0;L; 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;; +3342;SQUARE HOON;So;0;L; 30DB 30FC 30F3;;;;N;SQUARED HOON;;;; +3343;SQUARE MAIKURO;So;0;L; 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;; +3344;SQUARE MAIRU;So;0;L; 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;; +3345;SQUARE MAHHA;So;0;L; 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;; +3346;SQUARE MARUKU;So;0;L; 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;; +3347;SQUARE MANSYON;So;0;L; 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;; +3348;SQUARE MIKURON;So;0;L; 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;; +3349;SQUARE MIRI;So;0;L; 30DF 30EA;;;;N;SQUARED MIRI;;;; +334A;SQUARE MIRIBAARU;So;0;L; 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;; +334B;SQUARE MEGA;So;0;L; 30E1 30AC;;;;N;SQUARED MEGA;;;; +334C;SQUARE MEGATON;So;0;L; 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;; +334D;SQUARE MEETORU;So;0;L; 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;; +334E;SQUARE YAADO;So;0;L; 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;; +334F;SQUARE YAARU;So;0;L; 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;; +3350;SQUARE YUAN;So;0;L; 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;; +3351;SQUARE RITTORU;So;0;L; 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;; +3352;SQUARE RIRA;So;0;L; 30EA 30E9;;;;N;SQUARED RIRA;;;; +3353;SQUARE RUPII;So;0;L; 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;; +3354;SQUARE RUUBURU;So;0;L; 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;; +3355;SQUARE REMU;So;0;L; 30EC 30E0;;;;N;SQUARED REMU;;;; +3356;SQUARE RENTOGEN;So;0;L; 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;; +3357;SQUARE WATTO;So;0;L; 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;; +3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L; 0030 70B9;;;;N;;;;; +3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L; 0031 70B9;;;;N;;;;; +335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L; 0032 70B9;;;;N;;;;; +335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L; 0033 70B9;;;;N;;;;; +335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L; 0034 70B9;;;;N;;;;; +335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L; 0035 70B9;;;;N;;;;; +335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L; 0036 70B9;;;;N;;;;; +335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L; 0037 70B9;;;;N;;;;; +3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L; 0038 70B9;;;;N;;;;; +3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L; 0039 70B9;;;;N;;;;; +3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L; 0031 0030 70B9;;;;N;;;;; +3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L; 0031 0031 70B9;;;;N;;;;; +3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L; 0031 0032 70B9;;;;N;;;;; +3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L; 0031 0033 70B9;;;;N;;;;; +3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L; 0031 0034 70B9;;;;N;;;;; +3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L; 0031 0035 70B9;;;;N;;;;; +3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L; 0031 0036 70B9;;;;N;;;;; +3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L; 0031 0037 70B9;;;;N;;;;; +336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L; 0031 0038 70B9;;;;N;;;;; +336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L; 0031 0039 70B9;;;;N;;;;; +336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L; 0032 0030 70B9;;;;N;;;;; +336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L; 0032 0031 70B9;;;;N;;;;; +336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L; 0032 0032 70B9;;;;N;;;;; +336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L; 0032 0033 70B9;;;;N;;;;; +3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L; 0032 0034 70B9;;;;N;;;;; +3371;SQUARE HPA;So;0;L; 0068 0050 0061;;;;N;;;;; +3372;SQUARE DA;So;0;L; 0064 0061;;;;N;;;;; +3373;SQUARE AU;So;0;L; 0041 0055;;;;N;;;;; +3374;SQUARE BAR;So;0;L; 0062 0061 0072;;;;N;;;;; +3375;SQUARE OV;So;0;L; 006F 0056;;;;N;;;;; +3376;SQUARE PC;So;0;L; 0070 0063;;;;N;;;;; +3377;SQUARE DM;So;0;ON; 0064 006D;;;;N;;;;; +3378;SQUARE DM SQUARED;So;0;ON; 0064 006D 00B2;;;;N;;;;; +3379;SQUARE DM CUBED;So;0;ON; 0064 006D 00B3;;;;N;;;;; +337A;SQUARE IU;So;0;ON; 0049 0055;;;;N;;;;; +337B;SQUARE ERA NAME HEISEI;So;0;L; 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;; +337C;SQUARE ERA NAME SYOUWA;So;0;L; 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;; +337D;SQUARE ERA NAME TAISYOU;So;0;L; 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;; +337E;SQUARE ERA NAME MEIZI;So;0;L; 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;; +337F;SQUARE CORPORATION;So;0;L; 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;; +3380;SQUARE PA AMPS;So;0;L; 0070 0041;;;;N;SQUARED PA AMPS;;;; +3381;SQUARE NA;So;0;L; 006E 0041;;;;N;SQUARED NA;;;; +3382;SQUARE MU A;So;0;L; 03BC 0041;;;;N;SQUARED MU A;;;; +3383;SQUARE MA;So;0;L; 006D 0041;;;;N;SQUARED MA;;;; +3384;SQUARE KA;So;0;L; 006B 0041;;;;N;SQUARED KA;;;; +3385;SQUARE KB;So;0;L; 004B 0042;;;;N;SQUARED KB;;;; +3386;SQUARE MB;So;0;L; 004D 0042;;;;N;SQUARED MB;;;; +3387;SQUARE GB;So;0;L; 0047 0042;;;;N;SQUARED GB;;;; +3388;SQUARE CAL;So;0;L; 0063 0061 006C;;;;N;SQUARED CAL;;;; +3389;SQUARE KCAL;So;0;L; 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;; +338A;SQUARE PF;So;0;L; 0070 0046;;;;N;SQUARED PF;;;; +338B;SQUARE NF;So;0;L; 006E 0046;;;;N;SQUARED NF;;;; +338C;SQUARE MU F;So;0;L; 03BC 0046;;;;N;SQUARED MU F;;;; +338D;SQUARE MU G;So;0;L; 03BC 0067;;;;N;SQUARED MU G;;;; +338E;SQUARE MG;So;0;L; 006D 0067;;;;N;SQUARED MG;;;; +338F;SQUARE KG;So;0;L; 006B 0067;;;;N;SQUARED KG;;;; +3390;SQUARE HZ;So;0;L; 0048 007A;;;;N;SQUARED HZ;;;; +3391;SQUARE KHZ;So;0;L; 006B 0048 007A;;;;N;SQUARED KHZ;;;; +3392;SQUARE MHZ;So;0;L; 004D 0048 007A;;;;N;SQUARED MHZ;;;; +3393;SQUARE GHZ;So;0;L; 0047 0048 007A;;;;N;SQUARED GHZ;;;; +3394;SQUARE THZ;So;0;L; 0054 0048 007A;;;;N;SQUARED THZ;;;; +3395;SQUARE MU L;So;0;L; 03BC 2113;;;;N;SQUARED MU L;;;; +3396;SQUARE ML;So;0;L; 006D 2113;;;;N;SQUARED ML;;;; +3397;SQUARE DL;So;0;L; 0064 2113;;;;N;SQUARED DL;;;; +3398;SQUARE KL;So;0;L; 006B 2113;;;;N;SQUARED KL;;;; +3399;SQUARE FM;So;0;L; 0066 006D;;;;N;SQUARED FM;;;; +339A;SQUARE NM;So;0;L; 006E 006D;;;;N;SQUARED NM;;;; +339B;SQUARE MU M;So;0;L; 03BC 006D;;;;N;SQUARED MU M;;;; +339C;SQUARE MM;So;0;L; 006D 006D;;;;N;SQUARED MM;;;; +339D;SQUARE CM;So;0;L; 0063 006D;;;;N;SQUARED CM;;;; +339E;SQUARE KM;So;0;L; 006B 006D;;;;N;SQUARED KM;;;; +339F;SQUARE MM SQUARED;So;0;L; 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;; +33A0;SQUARE CM SQUARED;So;0;L; 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;; +33A1;SQUARE M SQUARED;So;0;L; 006D 00B2;;;;N;SQUARED M SQUARED;;;; +33A2;SQUARE KM SQUARED;So;0;L; 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;; +33A3;SQUARE MM CUBED;So;0;L; 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;; +33A4;SQUARE CM CUBED;So;0;L; 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;; +33A5;SQUARE M CUBED;So;0;L; 006D 00B3;;;;N;SQUARED M CUBED;;;; +33A6;SQUARE KM CUBED;So;0;L; 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;; +33A7;SQUARE M OVER S;So;0;L; 006D 2215 0073;;;;N;SQUARED M OVER S;;;; +33A8;SQUARE M OVER S SQUARED;So;0;L; 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;; +33A9;SQUARE PA;So;0;L; 0050 0061;;;;N;SQUARED PA;;;; +33AA;SQUARE KPA;So;0;L; 006B 0050 0061;;;;N;SQUARED KPA;;;; +33AB;SQUARE MPA;So;0;L; 004D 0050 0061;;;;N;SQUARED MPA;;;; +33AC;SQUARE GPA;So;0;L; 0047 0050 0061;;;;N;SQUARED GPA;;;; +33AD;SQUARE RAD;So;0;L; 0072 0061 0064;;;;N;SQUARED RAD;;;; +33AE;SQUARE RAD OVER S;So;0;L; 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;; +33AF;SQUARE RAD OVER S SQUARED;So;0;L; 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;; +33B0;SQUARE PS;So;0;L; 0070 0073;;;;N;SQUARED PS;;;; +33B1;SQUARE NS;So;0;L; 006E 0073;;;;N;SQUARED NS;;;; +33B2;SQUARE MU S;So;0;L; 03BC 0073;;;;N;SQUARED MU S;;;; +33B3;SQUARE MS;So;0;L; 006D 0073;;;;N;SQUARED MS;;;; +33B4;SQUARE PV;So;0;L; 0070 0056;;;;N;SQUARED PV;;;; +33B5;SQUARE NV;So;0;L; 006E 0056;;;;N;SQUARED NV;;;; +33B6;SQUARE MU V;So;0;L; 03BC 0056;;;;N;SQUARED MU V;;;; +33B7;SQUARE MV;So;0;L; 006D 0056;;;;N;SQUARED MV;;;; +33B8;SQUARE KV;So;0;L; 006B 0056;;;;N;SQUARED KV;;;; +33B9;SQUARE MV MEGA;So;0;L; 004D 0056;;;;N;SQUARED MV MEGA;;;; +33BA;SQUARE PW;So;0;L; 0070 0057;;;;N;SQUARED PW;;;; +33BB;SQUARE NW;So;0;L; 006E 0057;;;;N;SQUARED NW;;;; +33BC;SQUARE MU W;So;0;L; 03BC 0057;;;;N;SQUARED MU W;;;; +33BD;SQUARE MW;So;0;L; 006D 0057;;;;N;SQUARED MW;;;; +33BE;SQUARE KW;So;0;L; 006B 0057;;;;N;SQUARED KW;;;; +33BF;SQUARE MW MEGA;So;0;L; 004D 0057;;;;N;SQUARED MW MEGA;;;; +33C0;SQUARE K OHM;So;0;L; 006B 03A9;;;;N;SQUARED K OHM;;;; +33C1;SQUARE M OHM;So;0;L; 004D 03A9;;;;N;SQUARED M OHM;;;; +33C2;SQUARE AM;So;0;L; 0061 002E 006D 002E;;;;N;SQUARED AM;;;; +33C3;SQUARE BQ;So;0;L; 0042 0071;;;;N;SQUARED BQ;;;; +33C4;SQUARE CC;So;0;L; 0063 0063;;;;N;SQUARED CC;;;; +33C5;SQUARE CD;So;0;L; 0063 0064;;;;N;SQUARED CD;;;; +33C6;SQUARE C OVER KG;So;0;L; 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;; +33C7;SQUARE CO;So;0;L; 0043 006F 002E;;;;N;SQUARED CO;;;; +33C8;SQUARE DB;So;0;L; 0064 0042;;;;N;SQUARED DB;;;; +33C9;SQUARE GY;So;0;L; 0047 0079;;;;N;SQUARED GY;;;; +33CA;SQUARE HA;So;0;L; 0068 0061;;;;N;SQUARED HA;;;; +33CB;SQUARE HP;So;0;L; 0048 0050;;;;N;SQUARED HP;;;; +33CC;SQUARE IN;So;0;L; 0069 006E;;;;N;SQUARED IN;;;; +33CD;SQUARE KK;So;0;L; 004B 004B;;;;N;SQUARED KK;;;; +33CE;SQUARE KM CAPITAL;So;0;L; 004B 004D;;;;N;SQUARED KM CAPITAL;;;; +33CF;SQUARE KT;So;0;L; 006B 0074;;;;N;SQUARED KT;;;; +33D0;SQUARE LM;So;0;L; 006C 006D;;;;N;SQUARED LM;;;; +33D1;SQUARE LN;So;0;L; 006C 006E;;;;N;SQUARED LN;;;; +33D2;SQUARE LOG;So;0;L; 006C 006F 0067;;;;N;SQUARED LOG;;;; +33D3;SQUARE LX;So;0;L; 006C 0078;;;;N;SQUARED LX;;;; +33D4;SQUARE MB SMALL;So;0;L; 006D 0062;;;;N;SQUARED MB SMALL;;;; +33D5;SQUARE MIL;So;0;L; 006D 0069 006C;;;;N;SQUARED MIL;;;; +33D6;SQUARE MOL;So;0;L; 006D 006F 006C;;;;N;SQUARED MOL;;;; +33D7;SQUARE PH;So;0;L; 0050 0048;;;;N;SQUARED PH;;;; +33D8;SQUARE PM;So;0;L; 0070 002E 006D 002E;;;;N;SQUARED PM;;;; +33D9;SQUARE PPM;So;0;L; 0050 0050 004D;;;;N;SQUARED PPM;;;; +33DA;SQUARE PR;So;0;L; 0050 0052;;;;N;SQUARED PR;;;; +33DB;SQUARE SR;So;0;L; 0073 0072;;;;N;SQUARED SR;;;; +33DC;SQUARE SV;So;0;L; 0053 0076;;;;N;SQUARED SV;;;; +33DD;SQUARE WB;So;0;L; 0057 0062;;;;N;SQUARED WB;;;; +33DE;SQUARE V OVER M;So;0;ON; 0056 2215 006D;;;;N;;;;; +33DF;SQUARE A OVER M;So;0;ON; 0041 2215 006D;;;;N;;;;; +33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L; 0031 65E5;;;;N;;;;; +33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L; 0032 65E5;;;;N;;;;; +33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L; 0033 65E5;;;;N;;;;; +33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L; 0034 65E5;;;;N;;;;; +33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L; 0035 65E5;;;;N;;;;; +33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L; 0036 65E5;;;;N;;;;; +33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L; 0037 65E5;;;;N;;;;; +33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L; 0038 65E5;;;;N;;;;; +33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L; 0039 65E5;;;;N;;;;; +33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L; 0031 0030 65E5;;;;N;;;;; +33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L; 0031 0031 65E5;;;;N;;;;; +33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L; 0031 0032 65E5;;;;N;;;;; +33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L; 0031 0033 65E5;;;;N;;;;; +33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L; 0031 0034 65E5;;;;N;;;;; +33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L; 0031 0035 65E5;;;;N;;;;; +33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L; 0031 0036 65E5;;;;N;;;;; +33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L; 0031 0037 65E5;;;;N;;;;; +33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L; 0031 0038 65E5;;;;N;;;;; +33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L; 0031 0039 65E5;;;;N;;;;; +33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L; 0032 0030 65E5;;;;N;;;;; +33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L; 0032 0031 65E5;;;;N;;;;; +33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L; 0032 0032 65E5;;;;N;;;;; +33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L; 0032 0033 65E5;;;;N;;;;; +33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L; 0032 0034 65E5;;;;N;;;;; +33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L; 0032 0035 65E5;;;;N;;;;; +33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L; 0032 0036 65E5;;;;N;;;;; +33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L; 0032 0037 65E5;;;;N;;;;; +33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L; 0032 0038 65E5;;;;N;;;;; +33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L; 0032 0039 65E5;;;;N;;;;; +33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L; 0033 0030 65E5;;;;N;;;;; +33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;; +33FF;SQUARE GAL;So;0;ON; 0067 0061 006C;;;;N;;;;; +3400;;Lo;0;L;;;;;N;;;;; +4DB5;;Lo;0;L;;;;;N;;;;; +4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;; +4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;; +4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;; +4DC3;HEXAGRAM FOR YOUTHFUL FOLLY;So;0;ON;;;;;N;;;;; +4DC4;HEXAGRAM FOR WAITING;So;0;ON;;;;;N;;;;; +4DC5;HEXAGRAM FOR CONFLICT;So;0;ON;;;;;N;;;;; +4DC6;HEXAGRAM FOR THE ARMY;So;0;ON;;;;;N;;;;; +4DC7;HEXAGRAM FOR HOLDING TOGETHER;So;0;ON;;;;;N;;;;; +4DC8;HEXAGRAM FOR SMALL TAMING;So;0;ON;;;;;N;;;;; +4DC9;HEXAGRAM FOR TREADING;So;0;ON;;;;;N;;;;; +4DCA;HEXAGRAM FOR PEACE;So;0;ON;;;;;N;;;;; +4DCB;HEXAGRAM FOR STANDSTILL;So;0;ON;;;;;N;;;;; +4DCC;HEXAGRAM FOR FELLOWSHIP;So;0;ON;;;;;N;;;;; +4DCD;HEXAGRAM FOR GREAT POSSESSION;So;0;ON;;;;;N;;;;; +4DCE;HEXAGRAM FOR MODESTY;So;0;ON;;;;;N;;;;; +4DCF;HEXAGRAM FOR ENTHUSIASM;So;0;ON;;;;;N;;;;; +4DD0;HEXAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;; +4DD1;HEXAGRAM FOR WORK ON THE DECAYED;So;0;ON;;;;;N;;;;; +4DD2;HEXAGRAM FOR APPROACH;So;0;ON;;;;;N;;;;; +4DD3;HEXAGRAM FOR CONTEMPLATION;So;0;ON;;;;;N;;;;; +4DD4;HEXAGRAM FOR BITING THROUGH;So;0;ON;;;;;N;;;;; +4DD5;HEXAGRAM FOR GRACE;So;0;ON;;;;;N;;;;; +4DD6;HEXAGRAM FOR SPLITTING APART;So;0;ON;;;;;N;;;;; +4DD7;HEXAGRAM FOR RETURN;So;0;ON;;;;;N;;;;; +4DD8;HEXAGRAM FOR INNOCENCE;So;0;ON;;;;;N;;;;; +4DD9;HEXAGRAM FOR GREAT TAMING;So;0;ON;;;;;N;;;;; +4DDA;HEXAGRAM FOR MOUTH CORNERS;So;0;ON;;;;;N;;;;; +4DDB;HEXAGRAM FOR GREAT PREPONDERANCE;So;0;ON;;;;;N;;;;; +4DDC;HEXAGRAM FOR THE ABYSMAL WATER;So;0;ON;;;;;N;;;;; +4DDD;HEXAGRAM FOR THE CLINGING FIRE;So;0;ON;;;;;N;;;;; +4DDE;HEXAGRAM FOR INFLUENCE;So;0;ON;;;;;N;;;;; +4DDF;HEXAGRAM FOR DURATION;So;0;ON;;;;;N;;;;; +4DE0;HEXAGRAM FOR RETREAT;So;0;ON;;;;;N;;;;; +4DE1;HEXAGRAM FOR GREAT POWER;So;0;ON;;;;;N;;;;; +4DE2;HEXAGRAM FOR PROGRESS;So;0;ON;;;;;N;;;;; +4DE3;HEXAGRAM FOR DARKENING OF THE LIGHT;So;0;ON;;;;;N;;;;; +4DE4;HEXAGRAM FOR THE FAMILY;So;0;ON;;;;;N;;;;; +4DE5;HEXAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;; +4DE6;HEXAGRAM FOR OBSTRUCTION;So;0;ON;;;;;N;;;;; +4DE7;HEXAGRAM FOR DELIVERANCE;So;0;ON;;;;;N;;;;; +4DE8;HEXAGRAM FOR DECREASE;So;0;ON;;;;;N;;;;; +4DE9;HEXAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;; +4DEA;HEXAGRAM FOR BREAKTHROUGH;So;0;ON;;;;;N;;;;; +4DEB;HEXAGRAM FOR COMING TO MEET;So;0;ON;;;;;N;;;;; +4DEC;HEXAGRAM FOR GATHERING TOGETHER;So;0;ON;;;;;N;;;;; +4DED;HEXAGRAM FOR PUSHING UPWARD;So;0;ON;;;;;N;;;;; +4DEE;HEXAGRAM FOR OPPRESSION;So;0;ON;;;;;N;;;;; +4DEF;HEXAGRAM FOR THE WELL;So;0;ON;;;;;N;;;;; +4DF0;HEXAGRAM FOR REVOLUTION;So;0;ON;;;;;N;;;;; +4DF1;HEXAGRAM FOR THE CAULDRON;So;0;ON;;;;;N;;;;; +4DF2;HEXAGRAM FOR THE AROUSING THUNDER;So;0;ON;;;;;N;;;;; +4DF3;HEXAGRAM FOR THE KEEPING STILL MOUNTAIN;So;0;ON;;;;;N;;;;; +4DF4;HEXAGRAM FOR DEVELOPMENT;So;0;ON;;;;;N;;;;; +4DF5;HEXAGRAM FOR THE MARRYING MAIDEN;So;0;ON;;;;;N;;;;; +4DF6;HEXAGRAM FOR ABUNDANCE;So;0;ON;;;;;N;;;;; +4DF7;HEXAGRAM FOR THE WANDERER;So;0;ON;;;;;N;;;;; +4DF8;HEXAGRAM FOR THE GENTLE WIND;So;0;ON;;;;;N;;;;; +4DF9;HEXAGRAM FOR THE JOYOUS LAKE;So;0;ON;;;;;N;;;;; +4DFA;HEXAGRAM FOR DISPERSION;So;0;ON;;;;;N;;;;; +4DFB;HEXAGRAM FOR LIMITATION;So;0;ON;;;;;N;;;;; +4DFC;HEXAGRAM FOR INNER TRUTH;So;0;ON;;;;;N;;;;; +4DFD;HEXAGRAM FOR SMALL PREPONDERANCE;So;0;ON;;;;;N;;;;; +4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;; +4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;; +4E00;;Lo;0;L;;;;;N;;;;; +9FC3;;Lo;0;L;;;;;N;;;;; +A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; +A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; +A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; +A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;; +A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;; +A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;; +A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;; +A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;; +A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;; +A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;; +A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;; +A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;; +A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;; +A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;; +A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;; +A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;; +A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;; +A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;; +A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;; +A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;; +A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;; +A015;YI SYLLABLE WU;Lm;0;L;;;;;N;;;;; +A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;; +A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;; +A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;; +A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;; +A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;; +A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;; +A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;; +A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;; +A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;; +A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;; +A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;; +A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;; +A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;; +A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;; +A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;; +A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;; +A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;; +A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;; +A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;; +A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;; +A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;; +A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;; +A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;; +A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;; +A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;; +A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;; +A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;; +A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;; +A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;; +A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;; +A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;; +A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;; +A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;; +A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;; +A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;; +A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;; +A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;; +A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;; +A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;; +A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;; +A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;; +A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;; +A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;; +A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;; +A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;; +A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;; +A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;; +A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;; +A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;; +A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;; +A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;; +A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;; +A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;; +A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;; +A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;; +A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;; +A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;; +A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;; +A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;; +A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;; +A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;; +A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;; +A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;; +A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;; +A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;; +A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;; +A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;; +A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;; +A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;; +A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;; +A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;; +A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;; +A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;; +A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;; +A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;; +A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;; +A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;; +A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;; +A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;; +A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;; +A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;; +A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;; +A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;; +A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;; +A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;; +A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;; +A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;; +A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;; +A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;; +A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;; +A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;; +A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;; +A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;; +A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;; +A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;; +A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;; +A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;; +A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;; +A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;; +A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;; +A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;; +A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;; +A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;; +A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;; +A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;; +A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;; +A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;; +A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;; +A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;; +A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;; +A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;; +A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;; +A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;; +A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;; +A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;; +A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;; +A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;; +A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;; +A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;; +A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;; +A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;; +A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;; +A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;; +A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;; +A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;; +A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;; +A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;; +A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;; +A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;; +A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;; +A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;; +A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;; +A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;; +A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;; +A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;; +A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;; +A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;; +A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;; +A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;; +A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;; +A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;; +A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;; +A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;; +A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;; +A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;; +A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;; +A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;; +A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;; +A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;; +A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;; +A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;; +A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;; +A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;; +A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;; +A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;; +A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;; +A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;; +A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;; +A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;; +A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;; +A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;; +A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;; +A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;; +A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;; +A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;; +A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;; +A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;; +A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;; +A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;; +A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;; +A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;; +A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;; +A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;; +A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;; +A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;; +A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;; +A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;; +A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;; +A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;; +A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;; +A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;; +A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;; +A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;; +A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;; +A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;; +A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;; +A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;; +A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;; +A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;; +A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;; +A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;; +A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;; +A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;; +A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;; +A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;; +A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;; +A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;; +A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;; +A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;; +A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;; +A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;; +A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;; +A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;; +A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;; +A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;; +A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;; +A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;; +A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;; +A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;; +A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;; +A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;; +A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;; +A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;; +A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;; +A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;; +A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;; +A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;; +A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;; +A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;; +A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;; +A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;; +A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;; +A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;; +A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;; +A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;; +A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;; +A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;; +A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;; +A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;; +A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;; +A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;; +A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;; +A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;; +A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;; +A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;; +A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;; +A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;; +A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;; +A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;; +A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;; +A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;; +A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;; +A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;; +A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;; +A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;; +A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;; +A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;; +A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;; +A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;; +A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;; +A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;; +A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;; +A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;; +A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;; +A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;; +A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;; +A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;; +A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;; +A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;; +A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;; +A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;; +A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;; +A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;; +A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;; +A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;; +A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;; +A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;; +A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;; +A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;; +A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;; +A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;; +A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;; +A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;; +A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;; +A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;; +A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;; +A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;; +A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;; +A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;; +A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;; +A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;; +A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;; +A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;; +A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;; +A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;; +A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;; +A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;; +A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;; +A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;; +A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;; +A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;; +A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;; +A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;; +A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;; +A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;; +A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;; +A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;; +A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;; +A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;; +A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;; +A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;; +A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;; +A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;; +A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;; +A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;; +A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;; +A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;; +A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;; +A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;; +A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;; +A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;; +A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;; +A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; +A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;; +A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;; +A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;; +A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;; +A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;; +A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; +A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;; +A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;; +A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;; +A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; +A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;; +A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;; +A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; +A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;; +A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;; +A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;; +A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; +A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;; +A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;; +A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;; +A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;; +A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;; +A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;; +A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;; +A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;; +A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;; +A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;; +A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;; +A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;; +A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;; +A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;; +A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;; +A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;; +A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;; +A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;; +A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;; +A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;; +A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;; +A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;; +A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;; +A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;; +A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;; +A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;; +A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;; +A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;; +A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;; +A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;; +A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;; +A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;; +A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;; +A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;; +A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;; +A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;; +A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;; +A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;; +A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;; +A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;; +A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;; +A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;; +A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;; +A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;; +A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;; +A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;; +A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;; +A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;; +A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;; +A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;; +A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;; +A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;; +A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;; +A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;; +A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;; +A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;; +A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;; +A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;; +A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;; +A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;; +A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;; +A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;; +A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;; +A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;; +A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;; +A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;; +A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;; +A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;; +A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;; +A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;; +A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;; +A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;; +A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;; +A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;; +A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;; +A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;; +A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;; +A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;; +A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;; +A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;; +A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;; +A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;; +A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;; +A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;; +A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;; +A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;; +A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;; +A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;; +A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;; +A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;; +A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;; +A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;; +A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;; +A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;; +A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;; +A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;; +A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;; +A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;; +A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;; +A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;; +A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;; +A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;; +A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;; +A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;; +A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;; +A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;; +A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;; +A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;; +A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;; +A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;; +A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;; +A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;; +A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;; +A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;; +A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;; +A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;; +A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;; +A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;; +A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;; +A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;; +A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;; +A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;; +A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;; +A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;; +A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;; +A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;; +A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;; +A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;; +A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;; +A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;; +A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;; +A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;; +A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;; +A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;; +A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;; +A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;; +A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;; +A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;; +A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;; +A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;; +A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;; +A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;; +A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;; +A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;; +A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;; +A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;; +A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;; +A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;; +A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;; +A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;; +A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;; +A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;; +A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;; +A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;; +A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;; +A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;; +A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;; +A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;; +A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;; +A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;; +A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;; +A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;; +A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;; +A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;; +A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;; +A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;; +A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;; +A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;; +A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;; +A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;; +A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;; +A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;; +A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;; +A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;; +A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;; +A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;; +A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;; +A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;; +A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;; +A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;; +A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;; +A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;; +A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;; +A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;; +A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;; +A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;; +A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;; +A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;; +A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;; +A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;; +A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;; +A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;; +A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;; +A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;; +A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;; +A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;; +A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;; +A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;; +A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;; +A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;; +A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;; +A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;; +A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;; +A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;; +A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;; +A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;; +A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;; +A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;; +A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;; +A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;; +A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;; +A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;; +A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;; +A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;; +A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;; +A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;; +A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;; +A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;; +A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;; +A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;; +A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;; +A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;; +A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;; +A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;; +A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;; +A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;; +A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;; +A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;; +A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;; +A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;; +A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;; +A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;; +A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;; +A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;; +A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;; +A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;; +A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;; +A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;; +A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;; +A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;; +A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;; +A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;; +A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;; +A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;; +A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;; +A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;; +A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;; +A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;; +A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;; +A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;; +A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;; +A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;; +A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;; +A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;; +A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;; +A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;; +A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;; +A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;; +A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;; +A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;; +A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;; +A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;; +A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;; +A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;; +A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;; +A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;; +A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;; +A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;; +A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;; +A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;; +A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;; +A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;; +A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;; +A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;; +A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;; +A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;; +A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;; +A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;; +A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;; +A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;; +A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;; +A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;; +A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;; +A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;; +A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;; +A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;; +A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;; +A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;; +A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;; +A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;; +A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;; +A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;; +A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;; +A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;; +A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;; +A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;; +A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;; +A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;; +A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;; +A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;; +A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;; +A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;; +A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;; +A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;; +A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;; +A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;; +A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;; +A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;; +A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;; +A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;; +A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;; +A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;; +A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;; +A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;; +A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;; +A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;; +A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;; +A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;; +A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;; +A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;; +A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;; +A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;; +A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;; +A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;; +A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;; +A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;; +A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;; +A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;; +A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;; +A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;; +A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;; +A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;; +A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;; +A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;; +A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;; +A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;; +A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;; +A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;; +A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;; +A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;; +A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;; +A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;; +A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;; +A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;; +A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;; +A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;; +A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;; +A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;; +A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;; +A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;; +A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;; +A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;; +A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;; +A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;; +A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;; +A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; +A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;; +A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;; +A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;; +A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;; +A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;; +A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;; +A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;; +A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; +A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;; +A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;; +A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; +A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;; +A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;; +A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; +A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;; +A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;; +A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; +A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;; +A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;; +A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;; +A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;; +A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;; +A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;; +A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;; +A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;; +A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;; +A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;; +A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;; +A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;; +A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;; +A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;; +A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;; +A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;; +A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;; +A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;; +A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;; +A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;; +A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;; +A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;; +A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;; +A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;; +A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;; +A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;; +A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;; +A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;; +A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;; +A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;; +A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;; +A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;; +A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;; +A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;; +A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;; +A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;; +A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;; +A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;; +A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;; +A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;; +A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;; +A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;; +A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;; +A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;; +A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;; +A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;; +A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;; +A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;; +A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;; +A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;; +A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;; +A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;; +A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;; +A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;; +A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;; +A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;; +A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;; +A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;; +A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;; +A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;; +A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;; +A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;; +A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;; +A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;; +A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;; +A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;; +A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;; +A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;; +A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;; +A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;; +A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;; +A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;; +A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;; +A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;; +A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;; +A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;; +A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;; +A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;; +A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;; +A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;; +A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;; +A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;; +A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;; +A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;; +A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;; +A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;; +A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;; +A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;; +A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;; +A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;; +A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;; +A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;; +A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;; +A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;; +A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;; +A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;; +A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;; +A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;; +A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;; +A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;; +A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;; +A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;; +A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;; +A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;; +A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;; +A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;; +A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;; +A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;; +A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;; +A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;; +A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;; +A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;; +A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;; +A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;; +A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;; +A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;; +A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;; +A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;; +A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;; +A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;; +A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;; +A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;; +A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;; +A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;; +A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;; +A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;; +A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;; +A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;; +A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;; +A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;; +A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;; +A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;; +A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;; +A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;; +A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;; +A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;; +A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;; +A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;; +A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;; +A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;; +A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;; +A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;; +A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;; +A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;; +A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;; +A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;; +A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;; +A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;; +A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;; +A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;; +A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;; +A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;; +A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;; +A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;; +A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;; +A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;; +A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;; +A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;; +A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;; +A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;; +A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;; +A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;; +A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;; +A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;; +A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;; +A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;; +A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;; +A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;; +A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;; +A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;; +A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;; +A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;; +A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;; +A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;; +A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;; +A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;; +A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;; +A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;; +A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;; +A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;; +A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;; +A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;; +A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;; +A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;; +A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;; +A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;; +A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;; +A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;; +A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;; +A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;; +A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;; +A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;; +A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;; +A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;; +A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;; +A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;; +A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;; +A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;; +A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;; +A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;; +A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;; +A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;; +A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;; +A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;; +A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;; +A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;; +A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;; +A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;; +A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;; +A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;; +A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;; +A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;; +A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;; +A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;; +A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;; +A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;; +A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;; +A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;; +A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;; +A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;; +A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;; +A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;; +A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;; +A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;; +A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;; +A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;; +A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;; +A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;; +A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;; +A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;; +A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;; +A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;; +A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;; +A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;; +A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;; +A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;; +A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;; +A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;; +A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;; +A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;; +A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;; +A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;; +A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;; +A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;; +A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;; +A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;; +A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;; +A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;; +A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;; +A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;; +A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;; +A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;; +A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;; +A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;; +A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;; +A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;; +A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;; +A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;; +A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;; +A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;; +A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;; +A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;; +A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;; +A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;; +A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;; +A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;; +A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;; +A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;; +A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;; +A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;; +A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;; +A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;; +A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;; +A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;; +A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;; +A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;; +A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;; +A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;; +A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;; +A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;; +A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;; +A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;; +A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;; +A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;; +A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;; +A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;; +A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;; +A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;; +A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;; +A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;; +A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;; +A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;; +A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;; +A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;; +A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;; +A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;; +A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;; +A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;; +A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;; +A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;; +A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;; +A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;; +A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;; +A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;; +A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;; +A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;; +A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;; +A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;; +A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;; +A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;; +A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;; +A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;; +A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;; +A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;; +A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;; +A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;; +A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;; +A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;; +A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;; +A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;; +A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;; +A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;; +A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;; +A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; +A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;; +A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;; +A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;; +A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;; +A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;; +A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;; +A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;; +A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;; +A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;; +A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; +A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;; +A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;; +A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; +A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;; +A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;; +A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;; +A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;; +A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;; +A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;; +A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;; +A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;; +A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;; +A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;; +A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;; +A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;; +A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;; +A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;; +A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;; +A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;; +A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;; +A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;; +A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;; +A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;; +A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;; +A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;; +A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;; +A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;; +A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;; +A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;; +A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;; +A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;; +A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;; +A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;; +A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;; +A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;; +A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;; +A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;; +A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;; +A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;; +A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;; +A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;; +A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;; +A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;; +A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;; +A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;; +A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;; +A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;; +A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;; +A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;; +A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;; +A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;; +A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;; +A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;; +A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;; +A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;; +A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;; +A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;; +A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;; +A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;; +A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;; +A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;; +A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;; +A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;; +A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;; +A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;; +A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;; +A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;; +A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;; +A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;; +A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;; +A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;; +A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;; +A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;; +A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;; +A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;; +A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;; +A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;; +A491;YI RADICAL LI;So;0;ON;;;;;N;;;;; +A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;; +A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;; +A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;; +A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;; +A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;; +A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;; +A498;YI RADICAL MI;So;0;ON;;;;;N;;;;; +A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;; +A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;; +A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;; +A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;; +A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;; +A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;; +A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;; +A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;; +A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;; +A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;; +A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;; +A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;; +A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;; +A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;; +A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;; +A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;; +A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;; +A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;; +A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;; +A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;; +A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;; +A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;; +A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;; +A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;; +A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;; +A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;; +A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;; +A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;; +A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;; +A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;; +A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;; +A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;; +A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;; +A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;; +A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;; +A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;; +A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;; +A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;; +A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;; +A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;; +A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;; +A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;; +A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;; +A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;; +A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;; +A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;; +A500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;; +A501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;; +A502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;; +A503;VAI SYLLABLE WEE;Lo;0;L;;;;;N;;;;; +A504;VAI SYLLABLE WEEN;Lo;0;L;;;;;N;;;;; +A505;VAI SYLLABLE PEE;Lo;0;L;;;;;N;;;;; +A506;VAI SYLLABLE BHEE;Lo;0;L;;;;;N;;;;; +A507;VAI SYLLABLE BEE;Lo;0;L;;;;;N;;;;; +A508;VAI SYLLABLE MBEE;Lo;0;L;;;;;N;;;;; +A509;VAI SYLLABLE KPEE;Lo;0;L;;;;;N;;;;; +A50A;VAI SYLLABLE MGBEE;Lo;0;L;;;;;N;;;;; +A50B;VAI SYLLABLE GBEE;Lo;0;L;;;;;N;;;;; +A50C;VAI SYLLABLE FEE;Lo;0;L;;;;;N;;;;; +A50D;VAI SYLLABLE VEE;Lo;0;L;;;;;N;;;;; +A50E;VAI SYLLABLE TEE;Lo;0;L;;;;;N;;;;; +A50F;VAI SYLLABLE THEE;Lo;0;L;;;;;N;;;;; +A510;VAI SYLLABLE DHEE;Lo;0;L;;;;;N;;;;; +A511;VAI SYLLABLE DHHEE;Lo;0;L;;;;;N;;;;; +A512;VAI SYLLABLE LEE;Lo;0;L;;;;;N;;;;; +A513;VAI SYLLABLE REE;Lo;0;L;;;;;N;;;;; +A514;VAI SYLLABLE DEE;Lo;0;L;;;;;N;;;;; +A515;VAI SYLLABLE NDEE;Lo;0;L;;;;;N;;;;; +A516;VAI SYLLABLE SEE;Lo;0;L;;;;;N;;;;; +A517;VAI SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; +A518;VAI SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; +A519;VAI SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; +A51A;VAI SYLLABLE CEE;Lo;0;L;;;;;N;;;;; +A51B;VAI SYLLABLE JEE;Lo;0;L;;;;;N;;;;; +A51C;VAI SYLLABLE NJEE;Lo;0;L;;;;;N;;;;; +A51D;VAI SYLLABLE YEE;Lo;0;L;;;;;N;;;;; +A51E;VAI SYLLABLE KEE;Lo;0;L;;;;;N;;;;; +A51F;VAI SYLLABLE NGGEE;Lo;0;L;;;;;N;;;;; +A520;VAI SYLLABLE GEE;Lo;0;L;;;;;N;;;;; +A521;VAI SYLLABLE MEE;Lo;0;L;;;;;N;;;;; +A522;VAI SYLLABLE NEE;Lo;0;L;;;;;N;;;;; +A523;VAI SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; +A524;VAI SYLLABLE I;Lo;0;L;;;;;N;;;;; +A525;VAI SYLLABLE IN;Lo;0;L;;;;;N;;;;; +A526;VAI SYLLABLE HI;Lo;0;L;;;;;N;;;;; +A527;VAI SYLLABLE HIN;Lo;0;L;;;;;N;;;;; +A528;VAI SYLLABLE WI;Lo;0;L;;;;;N;;;;; +A529;VAI SYLLABLE WIN;Lo;0;L;;;;;N;;;;; +A52A;VAI SYLLABLE PI;Lo;0;L;;;;;N;;;;; +A52B;VAI SYLLABLE BHI;Lo;0;L;;;;;N;;;;; +A52C;VAI SYLLABLE BI;Lo;0;L;;;;;N;;;;; +A52D;VAI SYLLABLE MBI;Lo;0;L;;;;;N;;;;; +A52E;VAI SYLLABLE KPI;Lo;0;L;;;;;N;;;;; +A52F;VAI SYLLABLE MGBI;Lo;0;L;;;;;N;;;;; +A530;VAI SYLLABLE GBI;Lo;0;L;;;;;N;;;;; +A531;VAI SYLLABLE FI;Lo;0;L;;;;;N;;;;; +A532;VAI SYLLABLE VI;Lo;0;L;;;;;N;;;;; +A533;VAI SYLLABLE TI;Lo;0;L;;;;;N;;;;; +A534;VAI SYLLABLE THI;Lo;0;L;;;;;N;;;;; +A535;VAI SYLLABLE DHI;Lo;0;L;;;;;N;;;;; +A536;VAI SYLLABLE DHHI;Lo;0;L;;;;;N;;;;; +A537;VAI SYLLABLE LI;Lo;0;L;;;;;N;;;;; +A538;VAI SYLLABLE RI;Lo;0;L;;;;;N;;;;; +A539;VAI SYLLABLE DI;Lo;0;L;;;;;N;;;;; +A53A;VAI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; +A53B;VAI SYLLABLE SI;Lo;0;L;;;;;N;;;;; +A53C;VAI SYLLABLE SHI;Lo;0;L;;;;;N;;;;; +A53D;VAI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +A53E;VAI SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; +A53F;VAI SYLLABLE CI;Lo;0;L;;;;;N;;;;; +A540;VAI SYLLABLE JI;Lo;0;L;;;;;N;;;;; +A541;VAI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; +A542;VAI SYLLABLE YI;Lo;0;L;;;;;N;;;;; +A543;VAI SYLLABLE KI;Lo;0;L;;;;;N;;;;; +A544;VAI SYLLABLE NGGI;Lo;0;L;;;;;N;;;;; +A545;VAI SYLLABLE GI;Lo;0;L;;;;;N;;;;; +A546;VAI SYLLABLE MI;Lo;0;L;;;;;N;;;;; +A547;VAI SYLLABLE NI;Lo;0;L;;;;;N;;;;; +A548;VAI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +A549;VAI SYLLABLE A;Lo;0;L;;;;;N;;;;; +A54A;VAI SYLLABLE AN;Lo;0;L;;;;;N;;;;; +A54B;VAI SYLLABLE NGAN;Lo;0;L;;;;;N;;;;; +A54C;VAI SYLLABLE HA;Lo;0;L;;;;;N;;;;; +A54D;VAI SYLLABLE HAN;Lo;0;L;;;;;N;;;;; +A54E;VAI SYLLABLE WA;Lo;0;L;;;;;N;;;;; +A54F;VAI SYLLABLE WAN;Lo;0;L;;;;;N;;;;; +A550;VAI SYLLABLE PA;Lo;0;L;;;;;N;;;;; +A551;VAI SYLLABLE BHA;Lo;0;L;;;;;N;;;;; +A552;VAI SYLLABLE BA;Lo;0;L;;;;;N;;;;; +A553;VAI SYLLABLE MBA;Lo;0;L;;;;;N;;;;; +A554;VAI SYLLABLE KPA;Lo;0;L;;;;;N;;;;; +A555;VAI SYLLABLE KPAN;Lo;0;L;;;;;N;;;;; +A556;VAI SYLLABLE MGBA;Lo;0;L;;;;;N;;;;; +A557;VAI SYLLABLE GBA;Lo;0;L;;;;;N;;;;; +A558;VAI SYLLABLE FA;Lo;0;L;;;;;N;;;;; +A559;VAI SYLLABLE VA;Lo;0;L;;;;;N;;;;; +A55A;VAI SYLLABLE TA;Lo;0;L;;;;;N;;;;; +A55B;VAI SYLLABLE THA;Lo;0;L;;;;;N;;;;; +A55C;VAI SYLLABLE DHA;Lo;0;L;;;;;N;;;;; +A55D;VAI SYLLABLE DHHA;Lo;0;L;;;;;N;;;;; +A55E;VAI SYLLABLE LA;Lo;0;L;;;;;N;;;;; +A55F;VAI SYLLABLE RA;Lo;0;L;;;;;N;;;;; +A560;VAI SYLLABLE DA;Lo;0;L;;;;;N;;;;; +A561;VAI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; +A562;VAI SYLLABLE SA;Lo;0;L;;;;;N;;;;; +A563;VAI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +A564;VAI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +A565;VAI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +A566;VAI SYLLABLE CA;Lo;0;L;;;;;N;;;;; +A567;VAI SYLLABLE JA;Lo;0;L;;;;;N;;;;; +A568;VAI SYLLABLE NJA;Lo;0;L;;;;;N;;;;; +A569;VAI SYLLABLE YA;Lo;0;L;;;;;N;;;;; +A56A;VAI SYLLABLE KA;Lo;0;L;;;;;N;;;;; +A56B;VAI SYLLABLE KAN;Lo;0;L;;;;;N;;;;; +A56C;VAI SYLLABLE NGGA;Lo;0;L;;;;;N;;;;; +A56D;VAI SYLLABLE GA;Lo;0;L;;;;;N;;;;; +A56E;VAI SYLLABLE MA;Lo;0;L;;;;;N;;;;; +A56F;VAI SYLLABLE NA;Lo;0;L;;;;;N;;;;; +A570;VAI SYLLABLE NYA;Lo;0;L;;;;;N;;;;; +A571;VAI SYLLABLE OO;Lo;0;L;;;;;N;;;;; +A572;VAI SYLLABLE OON;Lo;0;L;;;;;N;;;;; +A573;VAI SYLLABLE HOO;Lo;0;L;;;;;N;;;;; +A574;VAI SYLLABLE WOO;Lo;0;L;;;;;N;;;;; +A575;VAI SYLLABLE WOON;Lo;0;L;;;;;N;;;;; +A576;VAI SYLLABLE POO;Lo;0;L;;;;;N;;;;; +A577;VAI SYLLABLE BHOO;Lo;0;L;;;;;N;;;;; +A578;VAI SYLLABLE BOO;Lo;0;L;;;;;N;;;;; +A579;VAI SYLLABLE MBOO;Lo;0;L;;;;;N;;;;; +A57A;VAI SYLLABLE KPOO;Lo;0;L;;;;;N;;;;; +A57B;VAI SYLLABLE MGBOO;Lo;0;L;;;;;N;;;;; +A57C;VAI SYLLABLE GBOO;Lo;0;L;;;;;N;;;;; +A57D;VAI SYLLABLE FOO;Lo;0;L;;;;;N;;;;; +A57E;VAI SYLLABLE VOO;Lo;0;L;;;;;N;;;;; +A57F;VAI SYLLABLE TOO;Lo;0;L;;;;;N;;;;; +A580;VAI SYLLABLE THOO;Lo;0;L;;;;;N;;;;; +A581;VAI SYLLABLE DHOO;Lo;0;L;;;;;N;;;;; +A582;VAI SYLLABLE DHHOO;Lo;0;L;;;;;N;;;;; +A583;VAI SYLLABLE LOO;Lo;0;L;;;;;N;;;;; +A584;VAI SYLLABLE ROO;Lo;0;L;;;;;N;;;;; +A585;VAI SYLLABLE DOO;Lo;0;L;;;;;N;;;;; +A586;VAI SYLLABLE NDOO;Lo;0;L;;;;;N;;;;; +A587;VAI SYLLABLE SOO;Lo;0;L;;;;;N;;;;; +A588;VAI SYLLABLE SHOO;Lo;0;L;;;;;N;;;;; +A589;VAI SYLLABLE ZOO;Lo;0;L;;;;;N;;;;; +A58A;VAI SYLLABLE ZHOO;Lo;0;L;;;;;N;;;;; +A58B;VAI SYLLABLE COO;Lo;0;L;;;;;N;;;;; +A58C;VAI SYLLABLE JOO;Lo;0;L;;;;;N;;;;; +A58D;VAI SYLLABLE NJOO;Lo;0;L;;;;;N;;;;; +A58E;VAI SYLLABLE YOO;Lo;0;L;;;;;N;;;;; +A58F;VAI SYLLABLE KOO;Lo;0;L;;;;;N;;;;; +A590;VAI SYLLABLE NGGOO;Lo;0;L;;;;;N;;;;; +A591;VAI SYLLABLE GOO;Lo;0;L;;;;;N;;;;; +A592;VAI SYLLABLE MOO;Lo;0;L;;;;;N;;;;; +A593;VAI SYLLABLE NOO;Lo;0;L;;;;;N;;;;; +A594;VAI SYLLABLE NYOO;Lo;0;L;;;;;N;;;;; +A595;VAI SYLLABLE U;Lo;0;L;;;;;N;;;;; +A596;VAI SYLLABLE UN;Lo;0;L;;;;;N;;;;; +A597;VAI SYLLABLE HU;Lo;0;L;;;;;N;;;;; +A598;VAI SYLLABLE HUN;Lo;0;L;;;;;N;;;;; +A599;VAI SYLLABLE WU;Lo;0;L;;;;;N;;;;; +A59A;VAI SYLLABLE WUN;Lo;0;L;;;;;N;;;;; +A59B;VAI SYLLABLE PU;Lo;0;L;;;;;N;;;;; +A59C;VAI SYLLABLE BHU;Lo;0;L;;;;;N;;;;; +A59D;VAI SYLLABLE BU;Lo;0;L;;;;;N;;;;; +A59E;VAI SYLLABLE MBU;Lo;0;L;;;;;N;;;;; +A59F;VAI SYLLABLE KPU;Lo;0;L;;;;;N;;;;; +A5A0;VAI SYLLABLE MGBU;Lo;0;L;;;;;N;;;;; +A5A1;VAI SYLLABLE GBU;Lo;0;L;;;;;N;;;;; +A5A2;VAI SYLLABLE FU;Lo;0;L;;;;;N;;;;; +A5A3;VAI SYLLABLE VU;Lo;0;L;;;;;N;;;;; +A5A4;VAI SYLLABLE TU;Lo;0;L;;;;;N;;;;; +A5A5;VAI SYLLABLE THU;Lo;0;L;;;;;N;;;;; +A5A6;VAI SYLLABLE DHU;Lo;0;L;;;;;N;;;;; +A5A7;VAI SYLLABLE DHHU;Lo;0;L;;;;;N;;;;; +A5A8;VAI SYLLABLE LU;Lo;0;L;;;;;N;;;;; +A5A9;VAI SYLLABLE RU;Lo;0;L;;;;;N;;;;; +A5AA;VAI SYLLABLE DU;Lo;0;L;;;;;N;;;;; +A5AB;VAI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; +A5AC;VAI SYLLABLE SU;Lo;0;L;;;;;N;;;;; +A5AD;VAI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +A5AE;VAI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +A5AF;VAI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +A5B0;VAI SYLLABLE CU;Lo;0;L;;;;;N;;;;; +A5B1;VAI SYLLABLE JU;Lo;0;L;;;;;N;;;;; +A5B2;VAI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; +A5B3;VAI SYLLABLE YU;Lo;0;L;;;;;N;;;;; +A5B4;VAI SYLLABLE KU;Lo;0;L;;;;;N;;;;; +A5B5;VAI SYLLABLE NGGU;Lo;0;L;;;;;N;;;;; +A5B6;VAI SYLLABLE GU;Lo;0;L;;;;;N;;;;; +A5B7;VAI SYLLABLE MU;Lo;0;L;;;;;N;;;;; +A5B8;VAI SYLLABLE NU;Lo;0;L;;;;;N;;;;; +A5B9;VAI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +A5BA;VAI SYLLABLE O;Lo;0;L;;;;;N;;;;; +A5BB;VAI SYLLABLE ON;Lo;0;L;;;;;N;;;;; +A5BC;VAI SYLLABLE NGON;Lo;0;L;;;;;N;;;;; +A5BD;VAI SYLLABLE HO;Lo;0;L;;;;;N;;;;; +A5BE;VAI SYLLABLE HON;Lo;0;L;;;;;N;;;;; +A5BF;VAI SYLLABLE WO;Lo;0;L;;;;;N;;;;; +A5C0;VAI SYLLABLE WON;Lo;0;L;;;;;N;;;;; +A5C1;VAI SYLLABLE PO;Lo;0;L;;;;;N;;;;; +A5C2;VAI SYLLABLE BHO;Lo;0;L;;;;;N;;;;; +A5C3;VAI SYLLABLE BO;Lo;0;L;;;;;N;;;;; +A5C4;VAI SYLLABLE MBO;Lo;0;L;;;;;N;;;;; +A5C5;VAI SYLLABLE KPO;Lo;0;L;;;;;N;;;;; +A5C6;VAI SYLLABLE MGBO;Lo;0;L;;;;;N;;;;; +A5C7;VAI SYLLABLE GBO;Lo;0;L;;;;;N;;;;; +A5C8;VAI SYLLABLE GBON;Lo;0;L;;;;;N;;;;; +A5C9;VAI SYLLABLE FO;Lo;0;L;;;;;N;;;;; +A5CA;VAI SYLLABLE VO;Lo;0;L;;;;;N;;;;; +A5CB;VAI SYLLABLE TO;Lo;0;L;;;;;N;;;;; +A5CC;VAI SYLLABLE THO;Lo;0;L;;;;;N;;;;; +A5CD;VAI SYLLABLE DHO;Lo;0;L;;;;;N;;;;; +A5CE;VAI SYLLABLE DHHO;Lo;0;L;;;;;N;;;;; +A5CF;VAI SYLLABLE LO;Lo;0;L;;;;;N;;;;; +A5D0;VAI SYLLABLE RO;Lo;0;L;;;;;N;;;;; +A5D1;VAI SYLLABLE DO;Lo;0;L;;;;;N;;;;; +A5D2;VAI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; +A5D3;VAI SYLLABLE SO;Lo;0;L;;;;;N;;;;; +A5D4;VAI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +A5D5;VAI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +A5D6;VAI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +A5D7;VAI SYLLABLE CO;Lo;0;L;;;;;N;;;;; +A5D8;VAI SYLLABLE JO;Lo;0;L;;;;;N;;;;; +A5D9;VAI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; +A5DA;VAI SYLLABLE YO;Lo;0;L;;;;;N;;;;; +A5DB;VAI SYLLABLE KO;Lo;0;L;;;;;N;;;;; +A5DC;VAI SYLLABLE NGGO;Lo;0;L;;;;;N;;;;; +A5DD;VAI SYLLABLE GO;Lo;0;L;;;;;N;;;;; +A5DE;VAI SYLLABLE MO;Lo;0;L;;;;;N;;;;; +A5DF;VAI SYLLABLE NO;Lo;0;L;;;;;N;;;;; +A5E0;VAI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +A5E1;VAI SYLLABLE E;Lo;0;L;;;;;N;;;;; +A5E2;VAI SYLLABLE EN;Lo;0;L;;;;;N;;;;; +A5E3;VAI SYLLABLE NGEN;Lo;0;L;;;;;N;;;;; +A5E4;VAI SYLLABLE HE;Lo;0;L;;;;;N;;;;; +A5E5;VAI SYLLABLE HEN;Lo;0;L;;;;;N;;;;; +A5E6;VAI SYLLABLE WE;Lo;0;L;;;;;N;;;;; +A5E7;VAI SYLLABLE WEN;Lo;0;L;;;;;N;;;;; +A5E8;VAI SYLLABLE PE;Lo;0;L;;;;;N;;;;; +A5E9;VAI SYLLABLE BHE;Lo;0;L;;;;;N;;;;; +A5EA;VAI SYLLABLE BE;Lo;0;L;;;;;N;;;;; +A5EB;VAI SYLLABLE MBE;Lo;0;L;;;;;N;;;;; +A5EC;VAI SYLLABLE KPE;Lo;0;L;;;;;N;;;;; +A5ED;VAI SYLLABLE KPEN;Lo;0;L;;;;;N;;;;; +A5EE;VAI SYLLABLE MGBE;Lo;0;L;;;;;N;;;;; +A5EF;VAI SYLLABLE GBE;Lo;0;L;;;;;N;;;;; +A5F0;VAI SYLLABLE GBEN;Lo;0;L;;;;;N;;;;; +A5F1;VAI SYLLABLE FE;Lo;0;L;;;;;N;;;;; +A5F2;VAI SYLLABLE VE;Lo;0;L;;;;;N;;;;; +A5F3;VAI SYLLABLE TE;Lo;0;L;;;;;N;;;;; +A5F4;VAI SYLLABLE THE;Lo;0;L;;;;;N;;;;; +A5F5;VAI SYLLABLE DHE;Lo;0;L;;;;;N;;;;; +A5F6;VAI SYLLABLE DHHE;Lo;0;L;;;;;N;;;;; +A5F7;VAI SYLLABLE LE;Lo;0;L;;;;;N;;;;; +A5F8;VAI SYLLABLE RE;Lo;0;L;;;;;N;;;;; +A5F9;VAI SYLLABLE DE;Lo;0;L;;;;;N;;;;; +A5FA;VAI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; +A5FB;VAI SYLLABLE SE;Lo;0;L;;;;;N;;;;; +A5FC;VAI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +A5FD;VAI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +A5FE;VAI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +A5FF;VAI SYLLABLE CE;Lo;0;L;;;;;N;;;;; +A600;VAI SYLLABLE JE;Lo;0;L;;;;;N;;;;; +A601;VAI SYLLABLE NJE;Lo;0;L;;;;;N;;;;; +A602;VAI SYLLABLE YE;Lo;0;L;;;;;N;;;;; +A603;VAI SYLLABLE KE;Lo;0;L;;;;;N;;;;; +A604;VAI SYLLABLE NGGE;Lo;0;L;;;;;N;;;;; +A605;VAI SYLLABLE NGGEN;Lo;0;L;;;;;N;;;;; +A606;VAI SYLLABLE GE;Lo;0;L;;;;;N;;;;; +A607;VAI SYLLABLE GEN;Lo;0;L;;;;;N;;;;; +A608;VAI SYLLABLE ME;Lo;0;L;;;;;N;;;;; +A609;VAI SYLLABLE NE;Lo;0;L;;;;;N;;;;; +A60A;VAI SYLLABLE NYE;Lo;0;L;;;;;N;;;;; +A60B;VAI SYLLABLE NG;Lo;0;L;;;;;N;;;;; +A60C;VAI SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;; +A60D;VAI COMMA;Po;0;ON;;;;;N;;;;; +A60E;VAI FULL STOP;Po;0;ON;;;;;N;;;;; +A60F;VAI QUESTION MARK;Po;0;ON;;;;;N;;;;; +A610;VAI SYLLABLE NDOLE FA;Lo;0;L;;;;;N;;;;; +A611;VAI SYLLABLE NDOLE KA;Lo;0;L;;;;;N;;;;; +A612;VAI SYLLABLE NDOLE SOO;Lo;0;L;;;;;N;;;;; +A613;VAI SYMBOL FEENG;Lo;0;L;;;;;N;;;;; +A614;VAI SYMBOL KEENG;Lo;0;L;;;;;N;;;;; +A615;VAI SYMBOL TING;Lo;0;L;;;;;N;;;;; +A616;VAI SYMBOL NII;Lo;0;L;;;;;N;;;;; +A617;VAI SYMBOL BANG;Lo;0;L;;;;;N;;;;; +A618;VAI SYMBOL FAA;Lo;0;L;;;;;N;;;;; +A619;VAI SYMBOL TAA;Lo;0;L;;;;;N;;;;; +A61A;VAI SYMBOL DANG;Lo;0;L;;;;;N;;;;; +A61B;VAI SYMBOL DOONG;Lo;0;L;;;;;N;;;;; +A61C;VAI SYMBOL KUNG;Lo;0;L;;;;;N;;;;; +A61D;VAI SYMBOL TONG;Lo;0;L;;;;;N;;;;; +A61E;VAI SYMBOL DO-O;Lo;0;L;;;;;N;;;;; +A61F;VAI SYMBOL JONG;Lo;0;L;;;;;N;;;;; +A620;VAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A621;VAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A622;VAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A623;VAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A624;VAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A625;VAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A626;VAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A627;VAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A628;VAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A629;VAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A62A;VAI SYLLABLE NDOLE MA;Lo;0;L;;;;;N;;;;; +A62B;VAI SYLLABLE NDOLE DO;Lo;0;L;;;;;N;;;;; +A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641; +A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640 +A642;CYRILLIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;A643; +A643;CYRILLIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;A642;;A642 +A644;CYRILLIC CAPITAL LETTER REVERSED DZE;Lu;0;L;;;;;N;;;;A645; +A645;CYRILLIC SMALL LETTER REVERSED DZE;Ll;0;L;;;;;N;;;A644;;A644 +A646;CYRILLIC CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;A647; +A647;CYRILLIC SMALL LETTER IOTA;Ll;0;L;;;;;N;;;A646;;A646 +A648;CYRILLIC CAPITAL LETTER DJERV;Lu;0;L;;;;;N;;;;A649; +A649;CYRILLIC SMALL LETTER DJERV;Ll;0;L;;;;;N;;;A648;;A648 +A64A;CYRILLIC CAPITAL LETTER MONOGRAPH UK;Lu;0;L;;;;;N;;;;A64B; +A64B;CYRILLIC SMALL LETTER MONOGRAPH UK;Ll;0;L;;;;;N;;;A64A;;A64A +A64C;CYRILLIC CAPITAL LETTER BROAD OMEGA;Lu;0;L;;;;;N;;;;A64D; +A64D;CYRILLIC SMALL LETTER BROAD OMEGA;Ll;0;L;;;;;N;;;A64C;;A64C +A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F; +A64F;CYRILLIC SMALL LETTER NEUTRAL YER;Ll;0;L;;;;;N;;;A64E;;A64E +A650;CYRILLIC CAPITAL LETTER YERU WITH BACK YER;Lu;0;L;;;;;N;;;;A651; +A651;CYRILLIC SMALL LETTER YERU WITH BACK YER;Ll;0;L;;;;;N;;;A650;;A650 +A652;CYRILLIC CAPITAL LETTER IOTIFIED YAT;Lu;0;L;;;;;N;;;;A653; +A653;CYRILLIC SMALL LETTER IOTIFIED YAT;Ll;0;L;;;;;N;;;A652;;A652 +A654;CYRILLIC CAPITAL LETTER REVERSED YU;Lu;0;L;;;;;N;;;;A655; +A655;CYRILLIC SMALL LETTER REVERSED YU;Ll;0;L;;;;;N;;;A654;;A654 +A656;CYRILLIC CAPITAL LETTER IOTIFIED A;Lu;0;L;;;;;N;;;;A657; +A657;CYRILLIC SMALL LETTER IOTIFIED A;Ll;0;L;;;;;N;;;A656;;A656 +A658;CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A659; +A659;CYRILLIC SMALL LETTER CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A658;;A658 +A65A;CYRILLIC CAPITAL LETTER BLENDED YUS;Lu;0;L;;;;;N;;;;A65B; +A65B;CYRILLIC SMALL LETTER BLENDED YUS;Ll;0;L;;;;;N;;;A65A;;A65A +A65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D; +A65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C +A65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F; +A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E +A662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663; +A663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662 +A664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665; +A665;CYRILLIC SMALL LETTER SOFT EL;Ll;0;L;;;;;N;;;A664;;A664 +A666;CYRILLIC CAPITAL LETTER SOFT EM;Lu;0;L;;;;;N;;;;A667; +A667;CYRILLIC SMALL LETTER SOFT EM;Ll;0;L;;;;;N;;;A666;;A666 +A668;CYRILLIC CAPITAL LETTER MONOCULAR O;Lu;0;L;;;;;N;;;;A669; +A669;CYRILLIC SMALL LETTER MONOCULAR O;Ll;0;L;;;;;N;;;A668;;A668 +A66A;CYRILLIC CAPITAL LETTER BINOCULAR O;Lu;0;L;;;;;N;;;;A66B; +A66B;CYRILLIC SMALL LETTER BINOCULAR O;Ll;0;L;;;;;N;;;A66A;;A66A +A66C;CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O;Lu;0;L;;;;;N;;;;A66D; +A66D;CYRILLIC SMALL LETTER DOUBLE MONOCULAR O;Ll;0;L;;;;;N;;;A66C;;A66C +A66E;CYRILLIC LETTER MULTIOCULAR O;Lo;0;L;;;;;N;;;;; +A66F;COMBINING CYRILLIC VZMET;Mn;230;NSM;;;;;N;;;;; +A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;; +A67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;; +A67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;; +A67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;; +A67F;CYRILLIC PAYEROK;Lm;0;ON;;;;;N;;;;; +A680;CYRILLIC CAPITAL LETTER DWE;Lu;0;L;;;;;N;;;;A681; +A681;CYRILLIC SMALL LETTER DWE;Ll;0;L;;;;;N;;;A680;;A680 +A682;CYRILLIC CAPITAL LETTER DZWE;Lu;0;L;;;;;N;;;;A683; +A683;CYRILLIC SMALL LETTER DZWE;Ll;0;L;;;;;N;;;A682;;A682 +A684;CYRILLIC CAPITAL LETTER ZHWE;Lu;0;L;;;;;N;;;;A685; +A685;CYRILLIC SMALL LETTER ZHWE;Ll;0;L;;;;;N;;;A684;;A684 +A686;CYRILLIC CAPITAL LETTER CCHE;Lu;0;L;;;;;N;;;;A687; +A687;CYRILLIC SMALL LETTER CCHE;Ll;0;L;;;;;N;;;A686;;A686 +A688;CYRILLIC CAPITAL LETTER DZZE;Lu;0;L;;;;;N;;;;A689; +A689;CYRILLIC SMALL LETTER DZZE;Ll;0;L;;;;;N;;;A688;;A688 +A68A;CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;A68B; +A68B;CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;A68A;;A68A +A68C;CYRILLIC CAPITAL LETTER TWE;Lu;0;L;;;;;N;;;;A68D; +A68D;CYRILLIC SMALL LETTER TWE;Ll;0;L;;;;;N;;;A68C;;A68C +A68E;CYRILLIC CAPITAL LETTER TSWE;Lu;0;L;;;;;N;;;;A68F; +A68F;CYRILLIC SMALL LETTER TSWE;Ll;0;L;;;;;N;;;A68E;;A68E +A690;CYRILLIC CAPITAL LETTER TSSE;Lu;0;L;;;;;N;;;;A691; +A691;CYRILLIC SMALL LETTER TSSE;Ll;0;L;;;;;N;;;A690;;A690 +A692;CYRILLIC CAPITAL LETTER TCHE;Lu;0;L;;;;;N;;;;A693; +A693;CYRILLIC SMALL LETTER TCHE;Ll;0;L;;;;;N;;;A692;;A692 +A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695; +A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694 +A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697; +A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696 +A700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;; +A701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;; +A702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;; +A703;MODIFIER LETTER CHINESE TONE YANG SHANG;Sk;0;ON;;;;;N;;;;; +A704;MODIFIER LETTER CHINESE TONE YIN QU;Sk;0;ON;;;;;N;;;;; +A705;MODIFIER LETTER CHINESE TONE YANG QU;Sk;0;ON;;;;;N;;;;; +A706;MODIFIER LETTER CHINESE TONE YIN RU;Sk;0;ON;;;;;N;;;;; +A707;MODIFIER LETTER CHINESE TONE YANG RU;Sk;0;ON;;;;;N;;;;; +A708;MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A709;MODIFIER LETTER HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70A;MODIFIER LETTER MID DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70B;MODIFIER LETTER LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70C;MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70D;MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A70E;MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A70F;MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A710;MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A711;MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A712;MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A713;MODIFIER LETTER HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A714;MODIFIER LETTER MID LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A715;MODIFIER LETTER LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A716;MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A717;MODIFIER LETTER DOT VERTICAL BAR;Lm;0;ON;;;;;N;;;;; +A718;MODIFIER LETTER DOT SLASH;Lm;0;ON;;;;;N;;;;; +A719;MODIFIER LETTER DOT HORIZONTAL BAR;Lm;0;ON;;;;;N;;;;; +A71A;MODIFIER LETTER LOWER RIGHT CORNER ANGLE;Lm;0;ON;;;;;N;;;;; +A71B;MODIFIER LETTER RAISED UP ARROW;Lm;0;ON;;;;;N;;;;; +A71C;MODIFIER LETTER RAISED DOWN ARROW;Lm;0;ON;;;;;N;;;;; +A71D;MODIFIER LETTER RAISED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A71E;MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A71F;MODIFIER LETTER LOW INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A720;MODIFIER LETTER STRESS AND HIGH TONE;Sk;0;ON;;;;;N;;;;; +A721;MODIFIER LETTER STRESS AND LOW TONE;Sk;0;ON;;;;;N;;;;; +A722;LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF;Lu;0;L;;;;;N;;;;A723; +A723;LATIN SMALL LETTER EGYPTOLOGICAL ALEF;Ll;0;L;;;;;N;;;A722;;A722 +A724;LATIN CAPITAL LETTER EGYPTOLOGICAL AIN;Lu;0;L;;;;;N;;;;A725; +A725;LATIN SMALL LETTER EGYPTOLOGICAL AIN;Ll;0;L;;;;;N;;;A724;;A724 +A726;LATIN CAPITAL LETTER HENG;Lu;0;L;;;;;N;;;;A727; +A727;LATIN SMALL LETTER HENG;Ll;0;L;;;;;N;;;A726;;A726 +A728;LATIN CAPITAL LETTER TZ;Lu;0;L;;;;;N;;;;A729; +A729;LATIN SMALL LETTER TZ;Ll;0;L;;;;;N;;;A728;;A728 +A72A;LATIN CAPITAL LETTER TRESILLO;Lu;0;L;;;;;N;;;;A72B; +A72B;LATIN SMALL LETTER TRESILLO;Ll;0;L;;;;;N;;;A72A;;A72A +A72C;LATIN CAPITAL LETTER CUATRILLO;Lu;0;L;;;;;N;;;;A72D; +A72D;LATIN SMALL LETTER CUATRILLO;Ll;0;L;;;;;N;;;A72C;;A72C +A72E;LATIN CAPITAL LETTER CUATRILLO WITH COMMA;Lu;0;L;;;;;N;;;;A72F; +A72F;LATIN SMALL LETTER CUATRILLO WITH COMMA;Ll;0;L;;;;;N;;;A72E;;A72E +A730;LATIN LETTER SMALL CAPITAL F;Ll;0;L;;;;;N;;;;; +A731;LATIN LETTER SMALL CAPITAL S;Ll;0;L;;;;;N;;;;; +A732;LATIN CAPITAL LETTER AA;Lu;0;L;;;;;N;;;;A733; +A733;LATIN SMALL LETTER AA;Ll;0;L;;;;;N;;;A732;;A732 +A734;LATIN CAPITAL LETTER AO;Lu;0;L;;;;;N;;;;A735; +A735;LATIN SMALL LETTER AO;Ll;0;L;;;;;N;;;A734;;A734 +A736;LATIN CAPITAL LETTER AU;Lu;0;L;;;;;N;;;;A737; +A737;LATIN SMALL LETTER AU;Ll;0;L;;;;;N;;;A736;;A736 +A738;LATIN CAPITAL LETTER AV;Lu;0;L;;;;;N;;;;A739; +A739;LATIN SMALL LETTER AV;Ll;0;L;;;;;N;;;A738;;A738 +A73A;LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR;Lu;0;L;;;;;N;;;;A73B; +A73B;LATIN SMALL LETTER AV WITH HORIZONTAL BAR;Ll;0;L;;;;;N;;;A73A;;A73A +A73C;LATIN CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;A73D; +A73D;LATIN SMALL LETTER AY;Ll;0;L;;;;;N;;;A73C;;A73C +A73E;LATIN CAPITAL LETTER REVERSED C WITH DOT;Lu;0;L;;;;;N;;;;A73F; +A73F;LATIN SMALL LETTER REVERSED C WITH DOT;Ll;0;L;;;;;N;;;A73E;;A73E +A740;LATIN CAPITAL LETTER K WITH STROKE;Lu;0;L;;;;;N;;;;A741; +A741;LATIN SMALL LETTER K WITH STROKE;Ll;0;L;;;;;N;;;A740;;A740 +A742;LATIN CAPITAL LETTER K WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A743; +A743;LATIN SMALL LETTER K WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A742;;A742 +A744;LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A745; +A745;LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE;Ll;0;L;;;;;N;;;A744;;A744 +A746;LATIN CAPITAL LETTER BROKEN L;Lu;0;L;;;;;N;;;;A747; +A747;LATIN SMALL LETTER BROKEN L;Ll;0;L;;;;;N;;;A746;;A746 +A748;LATIN CAPITAL LETTER L WITH HIGH STROKE;Lu;0;L;;;;;N;;;;A749; +A749;LATIN SMALL LETTER L WITH HIGH STROKE;Ll;0;L;;;;;N;;;A748;;A748 +A74A;LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY;Lu;0;L;;;;;N;;;;A74B; +A74B;LATIN SMALL LETTER O WITH LONG STROKE OVERLAY;Ll;0;L;;;;;N;;;A74A;;A74A +A74C;LATIN CAPITAL LETTER O WITH LOOP;Lu;0;L;;;;;N;;;;A74D; +A74D;LATIN SMALL LETTER O WITH LOOP;Ll;0;L;;;;;N;;;A74C;;A74C +A74E;LATIN CAPITAL LETTER OO;Lu;0;L;;;;;N;;;;A74F; +A74F;LATIN SMALL LETTER OO;Ll;0;L;;;;;N;;;A74E;;A74E +A750;LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A751; +A751;LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A750;;A750 +A752;LATIN CAPITAL LETTER P WITH FLOURISH;Lu;0;L;;;;;N;;;;A753; +A753;LATIN SMALL LETTER P WITH FLOURISH;Ll;0;L;;;;;N;;;A752;;A752 +A754;LATIN CAPITAL LETTER P WITH SQUIRREL TAIL;Lu;0;L;;;;;N;;;;A755; +A755;LATIN SMALL LETTER P WITH SQUIRREL TAIL;Ll;0;L;;;;;N;;;A754;;A754 +A756;LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A757; +A757;LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A756;;A756 +A758;LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A759; +A759;LATIN SMALL LETTER Q WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A758;;A758 +A75A;LATIN CAPITAL LETTER R ROTUNDA;Lu;0;L;;;;;N;;;;A75B; +A75B;LATIN SMALL LETTER R ROTUNDA;Ll;0;L;;;;;N;;;A75A;;A75A +A75C;LATIN CAPITAL LETTER RUM ROTUNDA;Lu;0;L;;;;;N;;;;A75D; +A75D;LATIN SMALL LETTER RUM ROTUNDA;Ll;0;L;;;;;N;;;A75C;;A75C +A75E;LATIN CAPITAL LETTER V WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A75F; +A75F;LATIN SMALL LETTER V WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A75E;;A75E +A760;LATIN CAPITAL LETTER VY;Lu;0;L;;;;;N;;;;A761; +A761;LATIN SMALL LETTER VY;Ll;0;L;;;;;N;;;A760;;A760 +A762;LATIN CAPITAL LETTER VISIGOTHIC Z;Lu;0;L;;;;;N;;;;A763; +A763;LATIN SMALL LETTER VISIGOTHIC Z;Ll;0;L;;;;;N;;;A762;;A762 +A764;LATIN CAPITAL LETTER THORN WITH STROKE;Lu;0;L;;;;;N;;;;A765; +A765;LATIN SMALL LETTER THORN WITH STROKE;Ll;0;L;;;;;N;;;A764;;A764 +A766;LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A767; +A767;LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A766;;A766 +A768;LATIN CAPITAL LETTER VEND;Lu;0;L;;;;;N;;;;A769; +A769;LATIN SMALL LETTER VEND;Ll;0;L;;;;;N;;;A768;;A768 +A76A;LATIN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;A76B; +A76B;LATIN SMALL LETTER ET;Ll;0;L;;;;;N;;;A76A;;A76A +A76C;LATIN CAPITAL LETTER IS;Lu;0;L;;;;;N;;;;A76D; +A76D;LATIN SMALL LETTER IS;Ll;0;L;;;;;N;;;A76C;;A76C +A76E;LATIN CAPITAL LETTER CON;Lu;0;L;;;;;N;;;;A76F; +A76F;LATIN SMALL LETTER CON;Ll;0;L;;;;;N;;;A76E;;A76E +A770;MODIFIER LETTER US;Lm;0;L; A76F;;;;N;;;;; +A771;LATIN SMALL LETTER DUM;Ll;0;L;;;;;N;;;;; +A772;LATIN SMALL LETTER LUM;Ll;0;L;;;;;N;;;;; +A773;LATIN SMALL LETTER MUM;Ll;0;L;;;;;N;;;;; +A774;LATIN SMALL LETTER NUM;Ll;0;L;;;;;N;;;;; +A775;LATIN SMALL LETTER RUM;Ll;0;L;;;;;N;;;;; +A776;LATIN LETTER SMALL CAPITAL RUM;Ll;0;L;;;;;N;;;;; +A777;LATIN SMALL LETTER TUM;Ll;0;L;;;;;N;;;;; +A778;LATIN SMALL LETTER UM;Ll;0;L;;;;;N;;;;; +A779;LATIN CAPITAL LETTER INSULAR D;Lu;0;L;;;;;N;;;;A77A; +A77A;LATIN SMALL LETTER INSULAR D;Ll;0;L;;;;;N;;;A779;;A779 +A77B;LATIN CAPITAL LETTER INSULAR F;Lu;0;L;;;;;N;;;;A77C; +A77C;LATIN SMALL LETTER INSULAR F;Ll;0;L;;;;;N;;;A77B;;A77B +A77D;LATIN CAPITAL LETTER INSULAR G;Lu;0;L;;;;;N;;;;1D79; +A77E;LATIN CAPITAL LETTER TURNED INSULAR G;Lu;0;L;;;;;N;;;;A77F; +A77F;LATIN SMALL LETTER TURNED INSULAR G;Ll;0;L;;;;;N;;;A77E;;A77E +A780;LATIN CAPITAL LETTER TURNED L;Lu;0;L;;;;;N;;;;A781; +A781;LATIN SMALL LETTER TURNED L;Ll;0;L;;;;;N;;;A780;;A780 +A782;LATIN CAPITAL LETTER INSULAR R;Lu;0;L;;;;;N;;;;A783; +A783;LATIN SMALL LETTER INSULAR R;Ll;0;L;;;;;N;;;A782;;A782 +A784;LATIN CAPITAL LETTER INSULAR S;Lu;0;L;;;;;N;;;;A785; +A785;LATIN SMALL LETTER INSULAR S;Ll;0;L;;;;;N;;;A784;;A784 +A786;LATIN CAPITAL LETTER INSULAR T;Lu;0;L;;;;;N;;;;A787; +A787;LATIN SMALL LETTER INSULAR T;Ll;0;L;;;;;N;;;A786;;A786 +A788;MODIFIER LETTER LOW CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;;;;; +A789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;; +A78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;; +A78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C; +A78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B +A7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;; +A7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;; +A7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;; +A7FE;LATIN EPIGRAPHIC LETTER I LONGA;Lo;0;L;;;;;N;;;;; +A7FF;LATIN EPIGRAPHIC LETTER ARCHAIC M;Lo;0;L;;;;;N;;;;; +A800;SYLOTI NAGRI LETTER A;Lo;0;L;;;;;N;;;;; +A801;SYLOTI NAGRI LETTER I;Lo;0;L;;;;;N;;;;; +A802;SYLOTI NAGRI SIGN DVISVARA;Mn;0;NSM;;;;;N;;;;; +A803;SYLOTI NAGRI LETTER U;Lo;0;L;;;;;N;;;;; +A804;SYLOTI NAGRI LETTER E;Lo;0;L;;;;;N;;;;; +A805;SYLOTI NAGRI LETTER O;Lo;0;L;;;;;N;;;;; +A806;SYLOTI NAGRI SIGN HASANTA;Mn;9;NSM;;;;;N;;;;; +A807;SYLOTI NAGRI LETTER KO;Lo;0;L;;;;;N;;;;; +A808;SYLOTI NAGRI LETTER KHO;Lo;0;L;;;;;N;;;;; +A809;SYLOTI NAGRI LETTER GO;Lo;0;L;;;;;N;;;;; +A80A;SYLOTI NAGRI LETTER GHO;Lo;0;L;;;;;N;;;;; +A80B;SYLOTI NAGRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +A80C;SYLOTI NAGRI LETTER CO;Lo;0;L;;;;;N;;;;; +A80D;SYLOTI NAGRI LETTER CHO;Lo;0;L;;;;;N;;;;; +A80E;SYLOTI NAGRI LETTER JO;Lo;0;L;;;;;N;;;;; +A80F;SYLOTI NAGRI LETTER JHO;Lo;0;L;;;;;N;;;;; +A810;SYLOTI NAGRI LETTER TTO;Lo;0;L;;;;;N;;;;; +A811;SYLOTI NAGRI LETTER TTHO;Lo;0;L;;;;;N;;;;; +A812;SYLOTI NAGRI LETTER DDO;Lo;0;L;;;;;N;;;;; +A813;SYLOTI NAGRI LETTER DDHO;Lo;0;L;;;;;N;;;;; +A814;SYLOTI NAGRI LETTER TO;Lo;0;L;;;;;N;;;;; +A815;SYLOTI NAGRI LETTER THO;Lo;0;L;;;;;N;;;;; +A816;SYLOTI NAGRI LETTER DO;Lo;0;L;;;;;N;;;;; +A817;SYLOTI NAGRI LETTER DHO;Lo;0;L;;;;;N;;;;; +A818;SYLOTI NAGRI LETTER NO;Lo;0;L;;;;;N;;;;; +A819;SYLOTI NAGRI LETTER PO;Lo;0;L;;;;;N;;;;; +A81A;SYLOTI NAGRI LETTER PHO;Lo;0;L;;;;;N;;;;; +A81B;SYLOTI NAGRI LETTER BO;Lo;0;L;;;;;N;;;;; +A81C;SYLOTI NAGRI LETTER BHO;Lo;0;L;;;;;N;;;;; +A81D;SYLOTI NAGRI LETTER MO;Lo;0;L;;;;;N;;;;; +A81E;SYLOTI NAGRI LETTER RO;Lo;0;L;;;;;N;;;;; +A81F;SYLOTI NAGRI LETTER LO;Lo;0;L;;;;;N;;;;; +A820;SYLOTI NAGRI LETTER RRO;Lo;0;L;;;;;N;;;;; +A821;SYLOTI NAGRI LETTER SO;Lo;0;L;;;;;N;;;;; +A822;SYLOTI NAGRI LETTER HO;Lo;0;L;;;;;N;;;;; +A823;SYLOTI NAGRI VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +A824;SYLOTI NAGRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +A825;SYLOTI NAGRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +A826;SYLOTI NAGRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +A827;SYLOTI NAGRI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;; +A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;; +A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;; +A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;; +A840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;; +A841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;; +A842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;; +A843;PHAGS-PA LETTER NGA;Lo;0;L;;;;;N;;;;; +A844;PHAGS-PA LETTER CA;Lo;0;L;;;;;N;;;;; +A845;PHAGS-PA LETTER CHA;Lo;0;L;;;;;N;;;;; +A846;PHAGS-PA LETTER JA;Lo;0;L;;;;;N;;;;; +A847;PHAGS-PA LETTER NYA;Lo;0;L;;;;;N;;;;; +A848;PHAGS-PA LETTER TA;Lo;0;L;;;;;N;;;;; +A849;PHAGS-PA LETTER THA;Lo;0;L;;;;;N;;;;; +A84A;PHAGS-PA LETTER DA;Lo;0;L;;;;;N;;;;; +A84B;PHAGS-PA LETTER NA;Lo;0;L;;;;;N;;;;; +A84C;PHAGS-PA LETTER PA;Lo;0;L;;;;;N;;;;; +A84D;PHAGS-PA LETTER PHA;Lo;0;L;;;;;N;;;;; +A84E;PHAGS-PA LETTER BA;Lo;0;L;;;;;N;;;;; +A84F;PHAGS-PA LETTER MA;Lo;0;L;;;;;N;;;;; +A850;PHAGS-PA LETTER TSA;Lo;0;L;;;;;N;;;;; +A851;PHAGS-PA LETTER TSHA;Lo;0;L;;;;;N;;;;; +A852;PHAGS-PA LETTER DZA;Lo;0;L;;;;;N;;;;; +A853;PHAGS-PA LETTER WA;Lo;0;L;;;;;N;;;;; +A854;PHAGS-PA LETTER ZHA;Lo;0;L;;;;;N;;;;; +A855;PHAGS-PA LETTER ZA;Lo;0;L;;;;;N;;;;; +A856;PHAGS-PA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +A857;PHAGS-PA LETTER YA;Lo;0;L;;;;;N;;;;; +A858;PHAGS-PA LETTER RA;Lo;0;L;;;;;N;;;;; +A859;PHAGS-PA LETTER LA;Lo;0;L;;;;;N;;;;; +A85A;PHAGS-PA LETTER SHA;Lo;0;L;;;;;N;;;;; +A85B;PHAGS-PA LETTER SA;Lo;0;L;;;;;N;;;;; +A85C;PHAGS-PA LETTER HA;Lo;0;L;;;;;N;;;;; +A85D;PHAGS-PA LETTER A;Lo;0;L;;;;;N;;;;; +A85E;PHAGS-PA LETTER I;Lo;0;L;;;;;N;;;;; +A85F;PHAGS-PA LETTER U;Lo;0;L;;;;;N;;;;; +A860;PHAGS-PA LETTER E;Lo;0;L;;;;;N;;;;; +A861;PHAGS-PA LETTER O;Lo;0;L;;;;;N;;;;; +A862;PHAGS-PA LETTER QA;Lo;0;L;;;;;N;;;;; +A863;PHAGS-PA LETTER XA;Lo;0;L;;;;;N;;;;; +A864;PHAGS-PA LETTER FA;Lo;0;L;;;;;N;;;;; +A865;PHAGS-PA LETTER GGA;Lo;0;L;;;;;N;;;;; +A866;PHAGS-PA LETTER EE;Lo;0;L;;;;;N;;;;; +A867;PHAGS-PA SUBJOINED LETTER WA;Lo;0;L;;;;;N;;;;; +A868;PHAGS-PA SUBJOINED LETTER YA;Lo;0;L;;;;;N;;;;; +A869;PHAGS-PA LETTER TTA;Lo;0;L;;;;;N;;;;; +A86A;PHAGS-PA LETTER TTHA;Lo;0;L;;;;;N;;;;; +A86B;PHAGS-PA LETTER DDA;Lo;0;L;;;;;N;;;;; +A86C;PHAGS-PA LETTER NNA;Lo;0;L;;;;;N;;;;; +A86D;PHAGS-PA LETTER ALTERNATE YA;Lo;0;L;;;;;N;;;;; +A86E;PHAGS-PA LETTER VOICELESS SHA;Lo;0;L;;;;;N;;;;; +A86F;PHAGS-PA LETTER VOICED HA;Lo;0;L;;;;;N;;;;; +A870;PHAGS-PA LETTER ASPIRATED FA;Lo;0;L;;;;;N;;;;; +A871;PHAGS-PA SUBJOINED LETTER RA;Lo;0;L;;;;;N;;;;; +A872;PHAGS-PA SUPERFIXED LETTER RA;Lo;0;L;;;;;N;;;;; +A873;PHAGS-PA LETTER CANDRABINDU;Lo;0;L;;;;;N;;;;; +A874;PHAGS-PA SINGLE HEAD MARK;Po;0;ON;;;;;N;;;;; +A875;PHAGS-PA DOUBLE HEAD MARK;Po;0;ON;;;;;N;;;;; +A876;PHAGS-PA MARK SHAD;Po;0;ON;;;;;N;;;;; +A877;PHAGS-PA MARK DOUBLE SHAD;Po;0;ON;;;;;N;;;;; +A880;SAURASHTRA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +A881;SAURASHTRA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +A882;SAURASHTRA LETTER A;Lo;0;L;;;;;N;;;;; +A883;SAURASHTRA LETTER AA;Lo;0;L;;;;;N;;;;; +A884;SAURASHTRA LETTER I;Lo;0;L;;;;;N;;;;; +A885;SAURASHTRA LETTER II;Lo;0;L;;;;;N;;;;; +A886;SAURASHTRA LETTER U;Lo;0;L;;;;;N;;;;; +A887;SAURASHTRA LETTER UU;Lo;0;L;;;;;N;;;;; +A888;SAURASHTRA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +A889;SAURASHTRA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +A88A;SAURASHTRA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +A88B;SAURASHTRA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +A88C;SAURASHTRA LETTER E;Lo;0;L;;;;;N;;;;; +A88D;SAURASHTRA LETTER EE;Lo;0;L;;;;;N;;;;; +A88E;SAURASHTRA LETTER AI;Lo;0;L;;;;;N;;;;; +A88F;SAURASHTRA LETTER O;Lo;0;L;;;;;N;;;;; +A890;SAURASHTRA LETTER OO;Lo;0;L;;;;;N;;;;; +A891;SAURASHTRA LETTER AU;Lo;0;L;;;;;N;;;;; +A892;SAURASHTRA LETTER KA;Lo;0;L;;;;;N;;;;; +A893;SAURASHTRA LETTER KHA;Lo;0;L;;;;;N;;;;; +A894;SAURASHTRA LETTER GA;Lo;0;L;;;;;N;;;;; +A895;SAURASHTRA LETTER GHA;Lo;0;L;;;;;N;;;;; +A896;SAURASHTRA LETTER NGA;Lo;0;L;;;;;N;;;;; +A897;SAURASHTRA LETTER CA;Lo;0;L;;;;;N;;;;; +A898;SAURASHTRA LETTER CHA;Lo;0;L;;;;;N;;;;; +A899;SAURASHTRA LETTER JA;Lo;0;L;;;;;N;;;;; +A89A;SAURASHTRA LETTER JHA;Lo;0;L;;;;;N;;;;; +A89B;SAURASHTRA LETTER NYA;Lo;0;L;;;;;N;;;;; +A89C;SAURASHTRA LETTER TTA;Lo;0;L;;;;;N;;;;; +A89D;SAURASHTRA LETTER TTHA;Lo;0;L;;;;;N;;;;; +A89E;SAURASHTRA LETTER DDA;Lo;0;L;;;;;N;;;;; +A89F;SAURASHTRA LETTER DDHA;Lo;0;L;;;;;N;;;;; +A8A0;SAURASHTRA LETTER NNA;Lo;0;L;;;;;N;;;;; +A8A1;SAURASHTRA LETTER TA;Lo;0;L;;;;;N;;;;; +A8A2;SAURASHTRA LETTER THA;Lo;0;L;;;;;N;;;;; +A8A3;SAURASHTRA LETTER DA;Lo;0;L;;;;;N;;;;; +A8A4;SAURASHTRA LETTER DHA;Lo;0;L;;;;;N;;;;; +A8A5;SAURASHTRA LETTER NA;Lo;0;L;;;;;N;;;;; +A8A6;SAURASHTRA LETTER PA;Lo;0;L;;;;;N;;;;; +A8A7;SAURASHTRA LETTER PHA;Lo;0;L;;;;;N;;;;; +A8A8;SAURASHTRA LETTER BA;Lo;0;L;;;;;N;;;;; +A8A9;SAURASHTRA LETTER BHA;Lo;0;L;;;;;N;;;;; +A8AA;SAURASHTRA LETTER MA;Lo;0;L;;;;;N;;;;; +A8AB;SAURASHTRA LETTER YA;Lo;0;L;;;;;N;;;;; +A8AC;SAURASHTRA LETTER RA;Lo;0;L;;;;;N;;;;; +A8AD;SAURASHTRA LETTER LA;Lo;0;L;;;;;N;;;;; +A8AE;SAURASHTRA LETTER VA;Lo;0;L;;;;;N;;;;; +A8AF;SAURASHTRA LETTER SHA;Lo;0;L;;;;;N;;;;; +A8B0;SAURASHTRA LETTER SSA;Lo;0;L;;;;;N;;;;; +A8B1;SAURASHTRA LETTER SA;Lo;0;L;;;;;N;;;;; +A8B2;SAURASHTRA LETTER HA;Lo;0;L;;;;;N;;;;; +A8B3;SAURASHTRA LETTER LLA;Lo;0;L;;;;;N;;;;; +A8B4;SAURASHTRA CONSONANT SIGN HAARU;Mc;0;L;;;;;N;;;;; +A8B5;SAURASHTRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +A8B6;SAURASHTRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +A8B7;SAURASHTRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +A8B8;SAURASHTRA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +A8B9;SAURASHTRA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +A8BA;SAURASHTRA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +A8BB;SAURASHTRA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +A8BC;SAURASHTRA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;; +A8BD;SAURASHTRA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;; +A8BE;SAURASHTRA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +A8BF;SAURASHTRA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +A8C0;SAURASHTRA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +A8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +A8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +A8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +A8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +A8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;; +A8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;; +A8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A8D1;SAURASHTRA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A8D2;SAURASHTRA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A8D3;SAURASHTRA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A8D4;SAURASHTRA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A8D5;SAURASHTRA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A903;KAYAH LI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A904;KAYAH LI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A905;KAYAH LI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A906;KAYAH LI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A907;KAYAH LI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A908;KAYAH LI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A909;KAYAH LI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A90A;KAYAH LI LETTER KA;Lo;0;L;;;;;N;;;;; +A90B;KAYAH LI LETTER KHA;Lo;0;L;;;;;N;;;;; +A90C;KAYAH LI LETTER GA;Lo;0;L;;;;;N;;;;; +A90D;KAYAH LI LETTER NGA;Lo;0;L;;;;;N;;;;; +A90E;KAYAH LI LETTER SA;Lo;0;L;;;;;N;;;;; +A90F;KAYAH LI LETTER SHA;Lo;0;L;;;;;N;;;;; +A910;KAYAH LI LETTER ZA;Lo;0;L;;;;;N;;;;; +A911;KAYAH LI LETTER NYA;Lo;0;L;;;;;N;;;;; +A912;KAYAH LI LETTER TA;Lo;0;L;;;;;N;;;;; +A913;KAYAH LI LETTER HTA;Lo;0;L;;;;;N;;;;; +A914;KAYAH LI LETTER NA;Lo;0;L;;;;;N;;;;; +A915;KAYAH LI LETTER PA;Lo;0;L;;;;;N;;;;; +A916;KAYAH LI LETTER PHA;Lo;0;L;;;;;N;;;;; +A917;KAYAH LI LETTER MA;Lo;0;L;;;;;N;;;;; +A918;KAYAH LI LETTER DA;Lo;0;L;;;;;N;;;;; +A919;KAYAH LI LETTER BA;Lo;0;L;;;;;N;;;;; +A91A;KAYAH LI LETTER RA;Lo;0;L;;;;;N;;;;; +A91B;KAYAH LI LETTER YA;Lo;0;L;;;;;N;;;;; +A91C;KAYAH LI LETTER LA;Lo;0;L;;;;;N;;;;; +A91D;KAYAH LI LETTER WA;Lo;0;L;;;;;N;;;;; +A91E;KAYAH LI LETTER THA;Lo;0;L;;;;;N;;;;; +A91F;KAYAH LI LETTER HA;Lo;0;L;;;;;N;;;;; +A920;KAYAH LI LETTER VA;Lo;0;L;;;;;N;;;;; +A921;KAYAH LI LETTER CA;Lo;0;L;;;;;N;;;;; +A922;KAYAH LI LETTER A;Lo;0;L;;;;;N;;;;; +A923;KAYAH LI LETTER OE;Lo;0;L;;;;;N;;;;; +A924;KAYAH LI LETTER I;Lo;0;L;;;;;N;;;;; +A925;KAYAH LI LETTER OO;Lo;0;L;;;;;N;;;;; +A926;KAYAH LI VOWEL UE;Mn;0;NSM;;;;;N;;;;; +A927;KAYAH LI VOWEL E;Mn;0;NSM;;;;;N;;;;; +A928;KAYAH LI VOWEL U;Mn;0;NSM;;;;;N;;;;; +A929;KAYAH LI VOWEL EE;Mn;0;NSM;;;;;N;;;;; +A92A;KAYAH LI VOWEL O;Mn;0;NSM;;;;;N;;;;; +A92B;KAYAH LI TONE PLOPHU;Mn;220;NSM;;;;;N;;;;; +A92C;KAYAH LI TONE CALYA;Mn;220;NSM;;;;;N;;;;; +A92D;KAYAH LI TONE CALYA PLOPHU;Mn;220;NSM;;;;;N;;;;; +A92E;KAYAH LI SIGN CWI;Po;0;L;;;;;N;;;;; +A92F;KAYAH LI SIGN SHYA;Po;0;L;;;;;N;;;;; +A930;REJANG LETTER KA;Lo;0;L;;;;;N;;;;; +A931;REJANG LETTER GA;Lo;0;L;;;;;N;;;;; +A932;REJANG LETTER NGA;Lo;0;L;;;;;N;;;;; +A933;REJANG LETTER TA;Lo;0;L;;;;;N;;;;; +A934;REJANG LETTER DA;Lo;0;L;;;;;N;;;;; +A935;REJANG LETTER NA;Lo;0;L;;;;;N;;;;; +A936;REJANG LETTER PA;Lo;0;L;;;;;N;;;;; +A937;REJANG LETTER BA;Lo;0;L;;;;;N;;;;; +A938;REJANG LETTER MA;Lo;0;L;;;;;N;;;;; +A939;REJANG LETTER CA;Lo;0;L;;;;;N;;;;; +A93A;REJANG LETTER JA;Lo;0;L;;;;;N;;;;; +A93B;REJANG LETTER NYA;Lo;0;L;;;;;N;;;;; +A93C;REJANG LETTER SA;Lo;0;L;;;;;N;;;;; +A93D;REJANG LETTER RA;Lo;0;L;;;;;N;;;;; +A93E;REJANG LETTER LA;Lo;0;L;;;;;N;;;;; +A93F;REJANG LETTER YA;Lo;0;L;;;;;N;;;;; +A940;REJANG LETTER WA;Lo;0;L;;;;;N;;;;; +A941;REJANG LETTER HA;Lo;0;L;;;;;N;;;;; +A942;REJANG LETTER MBA;Lo;0;L;;;;;N;;;;; +A943;REJANG LETTER NGGA;Lo;0;L;;;;;N;;;;; +A944;REJANG LETTER NDA;Lo;0;L;;;;;N;;;;; +A945;REJANG LETTER NYJA;Lo;0;L;;;;;N;;;;; +A946;REJANG LETTER A;Lo;0;L;;;;;N;;;;; +A947;REJANG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +A948;REJANG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +A949;REJANG VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +A94A;REJANG VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +A94B;REJANG VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +A94C;REJANG VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +A94D;REJANG VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;; +A94E;REJANG VOWEL SIGN EA;Mn;0;NSM;;;;;N;;;;; +A94F;REJANG CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;; +A950;REJANG CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +A951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +A952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;; +A953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;; +A95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;; +AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;; +AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;; +AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;; +AA03;CHAM LETTER E;Lo;0;L;;;;;N;;;;; +AA04;CHAM LETTER AI;Lo;0;L;;;;;N;;;;; +AA05;CHAM LETTER O;Lo;0;L;;;;;N;;;;; +AA06;CHAM LETTER KA;Lo;0;L;;;;;N;;;;; +AA07;CHAM LETTER KHA;Lo;0;L;;;;;N;;;;; +AA08;CHAM LETTER GA;Lo;0;L;;;;;N;;;;; +AA09;CHAM LETTER GHA;Lo;0;L;;;;;N;;;;; +AA0A;CHAM LETTER NGUE;Lo;0;L;;;;;N;;;;; +AA0B;CHAM LETTER NGA;Lo;0;L;;;;;N;;;;; +AA0C;CHAM LETTER CHA;Lo;0;L;;;;;N;;;;; +AA0D;CHAM LETTER CHHA;Lo;0;L;;;;;N;;;;; +AA0E;CHAM LETTER JA;Lo;0;L;;;;;N;;;;; +AA0F;CHAM LETTER JHA;Lo;0;L;;;;;N;;;;; +AA10;CHAM LETTER NHUE;Lo;0;L;;;;;N;;;;; +AA11;CHAM LETTER NHA;Lo;0;L;;;;;N;;;;; +AA12;CHAM LETTER NHJA;Lo;0;L;;;;;N;;;;; +AA13;CHAM LETTER TA;Lo;0;L;;;;;N;;;;; +AA14;CHAM LETTER THA;Lo;0;L;;;;;N;;;;; +AA15;CHAM LETTER DA;Lo;0;L;;;;;N;;;;; +AA16;CHAM LETTER DHA;Lo;0;L;;;;;N;;;;; +AA17;CHAM LETTER NUE;Lo;0;L;;;;;N;;;;; +AA18;CHAM LETTER NA;Lo;0;L;;;;;N;;;;; +AA19;CHAM LETTER DDA;Lo;0;L;;;;;N;;;;; +AA1A;CHAM LETTER PA;Lo;0;L;;;;;N;;;;; +AA1B;CHAM LETTER PPA;Lo;0;L;;;;;N;;;;; +AA1C;CHAM LETTER PHA;Lo;0;L;;;;;N;;;;; +AA1D;CHAM LETTER BA;Lo;0;L;;;;;N;;;;; +AA1E;CHAM LETTER BHA;Lo;0;L;;;;;N;;;;; +AA1F;CHAM LETTER MUE;Lo;0;L;;;;;N;;;;; +AA20;CHAM LETTER MA;Lo;0;L;;;;;N;;;;; +AA21;CHAM LETTER BBA;Lo;0;L;;;;;N;;;;; +AA22;CHAM LETTER YA;Lo;0;L;;;;;N;;;;; +AA23;CHAM LETTER RA;Lo;0;L;;;;;N;;;;; +AA24;CHAM LETTER LA;Lo;0;L;;;;;N;;;;; +AA25;CHAM LETTER VA;Lo;0;L;;;;;N;;;;; +AA26;CHAM LETTER SSA;Lo;0;L;;;;;N;;;;; +AA27;CHAM LETTER SA;Lo;0;L;;;;;N;;;;; +AA28;CHAM LETTER HA;Lo;0;L;;;;;N;;;;; +AA29;CHAM VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +AA2A;CHAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +AA2B;CHAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +AA2C;CHAM VOWEL SIGN EI;Mn;0;NSM;;;;;N;;;;; +AA2D;CHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +AA2E;CHAM VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +AA2F;CHAM VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +AA30;CHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +AA31;CHAM VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +AA32;CHAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +AA33;CHAM CONSONANT SIGN YA;Mc;0;L;;;;;N;;;;; +AA34;CHAM CONSONANT SIGN RA;Mc;0;L;;;;;N;;;;; +AA35;CHAM CONSONANT SIGN LA;Mn;0;NSM;;;;;N;;;;; +AA36;CHAM CONSONANT SIGN WA;Mn;0;NSM;;;;;N;;;;; +AA40;CHAM LETTER FINAL K;Lo;0;L;;;;;N;;;;; +AA41;CHAM LETTER FINAL G;Lo;0;L;;;;;N;;;;; +AA42;CHAM LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +AA43;CHAM CONSONANT SIGN FINAL NG;Mn;0;NSM;;;;;N;;;;; +AA44;CHAM LETTER FINAL CH;Lo;0;L;;;;;N;;;;; +AA45;CHAM LETTER FINAL T;Lo;0;L;;;;;N;;;;; +AA46;CHAM LETTER FINAL N;Lo;0;L;;;;;N;;;;; +AA47;CHAM LETTER FINAL P;Lo;0;L;;;;;N;;;;; +AA48;CHAM LETTER FINAL Y;Lo;0;L;;;;;N;;;;; +AA49;CHAM LETTER FINAL R;Lo;0;L;;;;;N;;;;; +AA4A;CHAM LETTER FINAL L;Lo;0;L;;;;;N;;;;; +AA4B;CHAM LETTER FINAL SS;Lo;0;L;;;;;N;;;;; +AA4C;CHAM CONSONANT SIGN FINAL M;Mn;0;NSM;;;;;N;;;;; +AA4D;CHAM CONSONANT SIGN FINAL H;Mc;0;L;;;;;N;;;;; +AA50;CHAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +AA51;CHAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +AA52;CHAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +AA53;CHAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +AA54;CHAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +AA55;CHAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +AA56;CHAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +AA57;CHAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +AA58;CHAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +AA59;CHAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +AA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;; +AA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;; +AA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;; +AA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;; +AC00;;Lo;0;L;;;;;N;;;;; +D7A3;;Lo;0;L;;;;;N;;;;; +D800;;Cs;0;L;;;;;N;;;;; +DB7F;;Cs;0;L;;;;;N;;;;; +DB80;;Cs;0;L;;;;;N;;;;; +DBFF;;Cs;0;L;;;;;N;;;;; +DC00;;Cs;0;L;;;;;N;;;;; +DFFF;;Cs;0;L;;;;;N;;;;; +E000;;Co;0;L;;;;;N;;;;; +F8FF;;Co;0;L;;;;;N;;;;; +F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;; +F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;; +F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;; +F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;; +F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;; +F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;; +F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;; +F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;; +F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;; +F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;; +F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;; +F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;; +F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;; +F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;; +F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;; +F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;; +F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;; +F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;; +F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;; +F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;; +F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;; +F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;; +F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;; +F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;; +F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;; +F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;; +F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;; +F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;; +F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;; +F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;; +F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;; +F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;; +F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;; +F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;; +F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;; +F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;; +F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;; +F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;; +F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;; +F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;; +F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;; +F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;; +F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;; +F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;; +F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;; +F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;; +F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;; +F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;; +F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;; +F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;; +F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;; +F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;; +F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;; +F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;; +F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;; +F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;; +F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;; +F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;; +F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;; +F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;; +F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;; +F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;; +F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;; +F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;; +F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;; +F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;; +F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;; +F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;; +F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;; +F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;; +F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;; +F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;; +F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;; +F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;; +F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;; +F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;; +F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;; +F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;; +F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;; +F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;; +F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;; +F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;; +F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;; +F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;; +F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;; +F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;; +F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;; +F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;; +F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;; +F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;; +F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;; +F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;; +F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;; +F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;; +F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;; +F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;; +F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;; +F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;; +F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;; +F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;; +F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;; +F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;; +F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;; +F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;; +F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;; +F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;; +F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;; +F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;3;N;;;;; +F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;; +F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;; +F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;; +F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;; +F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;; +F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;; +F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;; +F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;10;N;;;;; +F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;; +F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;; +F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;; +F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;; +F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;2;N;;;;; +F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;; +F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;; +F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;; +F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;; +F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;; +F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;; +F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;; +F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;; +F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;; +F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;; +F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;; +F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;; +F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;; +F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;; +F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;; +F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;; +F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;; +F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;; +F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;; +F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;; +F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;; +F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;; +F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;; +F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;; +F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;; +F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;; +F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;; +F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;; +F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;; +F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;; +F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;; +F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;; +F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;; +F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;; +F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;; +F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;; +F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;; +F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;; +F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;; +F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;; +F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;; +F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;; +F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;; +F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;; +F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;; +F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;; +F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;; +F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;; +F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;; +F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;; +F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;; +F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;; +F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;; +F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;; +F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;; +F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;; +F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;; +F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;0;N;;;;; +F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;; +F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;; +F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;; +F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;; +F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;; +F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;; +F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;; +F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;; +F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;; +F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;; +F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;; +F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;; +F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;; +F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;; +F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;; +F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;; +F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;; +F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;; +F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;; +F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;; +F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;; +F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;; +F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;; +F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;; +F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;; +F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;; +F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;; +F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;; +F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;; +F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;; +F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;6;N;;;;; +F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;; +F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;6;N;;;;; +F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;; +F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;; +F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;; +F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;; +F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;; +F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;; +F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;; +F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;; +F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;; +F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;; +F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;; +F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;; +F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;; +F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;; +F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;; +F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;; +F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;; +F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;; +F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;; +F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;; +F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;; +F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;; +F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;; +F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;; +F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;; +F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;; +F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;; +F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;; +F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;; +F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;; +F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;; +F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;; +F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;; +F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;; +F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;; +F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;; +F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;; +F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;; +F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;; +F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;; +F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;; +F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;10;N;;;;; +F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;; +F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;; +FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;; +FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;; +FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;; +FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;; +FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;; +FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;; +FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;; +FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;; +FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;; +FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;; +FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;; +FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;; +FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;; +FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;; +FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;; +FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;; +FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;; +FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;; +FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;; +FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;; +FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;; +FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;; +FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;; +FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;; +FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;; +FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;; +FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;; +FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;; +FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;; +FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;; +FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;; +FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;*;;; +FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;; +FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;; +FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;; +FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;*;;; +FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;; +FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;; +FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;; +FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;; +FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;; +FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;; +FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;; +FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;; +FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;; +FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;; +FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;; +FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;; +FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;; +FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;; +FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;; +FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;; +FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;; +FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;; +FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;; +FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;; +FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;; +FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;; +FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;; +FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;; +FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;; +FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;; +FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;; +FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;; +FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;; +FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;; +FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;; +FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;; +FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;; +FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;; +FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;; +FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;; +FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;; +FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;; +FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;; +FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;; +FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;; +FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;; +FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;; +FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;; +FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;; +FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;; +FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;; +FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;; +FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;; +FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;; +FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;; +FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;; +FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;; +FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;; +FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;; +FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;; +FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;; +FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;; +FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;; +FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;; +FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;; +FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;; +FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;; +FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;; +FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;; +FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;; +FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;; +FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;; +FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;; +FA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;; +FA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;; +FA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;; +FA73;CJK COMPATIBILITY IDEOGRAPH-FA73;Lo;0;L;4F80;;;;N;;;;; +FA74;CJK COMPATIBILITY IDEOGRAPH-FA74;Lo;0;L;5145;;;;N;;;;; +FA75;CJK COMPATIBILITY IDEOGRAPH-FA75;Lo;0;L;5180;;;;N;;;;; +FA76;CJK COMPATIBILITY IDEOGRAPH-FA76;Lo;0;L;52C7;;;;N;;;;; +FA77;CJK COMPATIBILITY IDEOGRAPH-FA77;Lo;0;L;52FA;;;;N;;;;; +FA78;CJK COMPATIBILITY IDEOGRAPH-FA78;Lo;0;L;559D;;;;N;;;;; +FA79;CJK COMPATIBILITY IDEOGRAPH-FA79;Lo;0;L;5555;;;;N;;;;; +FA7A;CJK COMPATIBILITY IDEOGRAPH-FA7A;Lo;0;L;5599;;;;N;;;;; +FA7B;CJK COMPATIBILITY IDEOGRAPH-FA7B;Lo;0;L;55E2;;;;N;;;;; +FA7C;CJK COMPATIBILITY IDEOGRAPH-FA7C;Lo;0;L;585A;;;;N;;;;; +FA7D;CJK COMPATIBILITY IDEOGRAPH-FA7D;Lo;0;L;58B3;;;;N;;;;; +FA7E;CJK COMPATIBILITY IDEOGRAPH-FA7E;Lo;0;L;5944;;;;N;;;;; +FA7F;CJK COMPATIBILITY IDEOGRAPH-FA7F;Lo;0;L;5954;;;;N;;;;; +FA80;CJK COMPATIBILITY IDEOGRAPH-FA80;Lo;0;L;5A62;;;;N;;;;; +FA81;CJK COMPATIBILITY IDEOGRAPH-FA81;Lo;0;L;5B28;;;;N;;;;; +FA82;CJK COMPATIBILITY IDEOGRAPH-FA82;Lo;0;L;5ED2;;;;N;;;;; +FA83;CJK COMPATIBILITY IDEOGRAPH-FA83;Lo;0;L;5ED9;;;;N;;;;; +FA84;CJK COMPATIBILITY IDEOGRAPH-FA84;Lo;0;L;5F69;;;;N;;;;; +FA85;CJK COMPATIBILITY IDEOGRAPH-FA85;Lo;0;L;5FAD;;;;N;;;;; +FA86;CJK COMPATIBILITY IDEOGRAPH-FA86;Lo;0;L;60D8;;;;N;;;;; +FA87;CJK COMPATIBILITY IDEOGRAPH-FA87;Lo;0;L;614E;;;;N;;;;; +FA88;CJK COMPATIBILITY IDEOGRAPH-FA88;Lo;0;L;6108;;;;N;;;;; +FA89;CJK COMPATIBILITY IDEOGRAPH-FA89;Lo;0;L;618E;;;;N;;;;; +FA8A;CJK COMPATIBILITY IDEOGRAPH-FA8A;Lo;0;L;6160;;;;N;;;;; +FA8B;CJK COMPATIBILITY IDEOGRAPH-FA8B;Lo;0;L;61F2;;;;N;;;;; +FA8C;CJK COMPATIBILITY IDEOGRAPH-FA8C;Lo;0;L;6234;;;;N;;;;; +FA8D;CJK COMPATIBILITY IDEOGRAPH-FA8D;Lo;0;L;63C4;;;;N;;;;; +FA8E;CJK COMPATIBILITY IDEOGRAPH-FA8E;Lo;0;L;641C;;;;N;;;;; +FA8F;CJK COMPATIBILITY IDEOGRAPH-FA8F;Lo;0;L;6452;;;;N;;;;; +FA90;CJK COMPATIBILITY IDEOGRAPH-FA90;Lo;0;L;6556;;;;N;;;;; +FA91;CJK COMPATIBILITY IDEOGRAPH-FA91;Lo;0;L;6674;;;;N;;;;; +FA92;CJK COMPATIBILITY IDEOGRAPH-FA92;Lo;0;L;6717;;;;N;;;;; +FA93;CJK COMPATIBILITY IDEOGRAPH-FA93;Lo;0;L;671B;;;;N;;;;; +FA94;CJK COMPATIBILITY IDEOGRAPH-FA94;Lo;0;L;6756;;;;N;;;;; +FA95;CJK COMPATIBILITY IDEOGRAPH-FA95;Lo;0;L;6B79;;;;N;;;;; +FA96;CJK COMPATIBILITY IDEOGRAPH-FA96;Lo;0;L;6BBA;;;;N;;;;; +FA97;CJK COMPATIBILITY IDEOGRAPH-FA97;Lo;0;L;6D41;;;;N;;;;; +FA98;CJK COMPATIBILITY IDEOGRAPH-FA98;Lo;0;L;6EDB;;;;N;;;;; +FA99;CJK COMPATIBILITY IDEOGRAPH-FA99;Lo;0;L;6ECB;;;;N;;;;; +FA9A;CJK COMPATIBILITY IDEOGRAPH-FA9A;Lo;0;L;6F22;;;;N;;;;; +FA9B;CJK COMPATIBILITY IDEOGRAPH-FA9B;Lo;0;L;701E;;;;N;;;;; +FA9C;CJK COMPATIBILITY IDEOGRAPH-FA9C;Lo;0;L;716E;;;;N;;;;; +FA9D;CJK COMPATIBILITY IDEOGRAPH-FA9D;Lo;0;L;77A7;;;;N;;;;; +FA9E;CJK COMPATIBILITY IDEOGRAPH-FA9E;Lo;0;L;7235;;;;N;;;;; +FA9F;CJK COMPATIBILITY IDEOGRAPH-FA9F;Lo;0;L;72AF;;;;N;;;;; +FAA0;CJK COMPATIBILITY IDEOGRAPH-FAA0;Lo;0;L;732A;;;;N;;;;; +FAA1;CJK COMPATIBILITY IDEOGRAPH-FAA1;Lo;0;L;7471;;;;N;;;;; +FAA2;CJK COMPATIBILITY IDEOGRAPH-FAA2;Lo;0;L;7506;;;;N;;;;; +FAA3;CJK COMPATIBILITY IDEOGRAPH-FAA3;Lo;0;L;753B;;;;N;;;;; +FAA4;CJK COMPATIBILITY IDEOGRAPH-FAA4;Lo;0;L;761D;;;;N;;;;; +FAA5;CJK COMPATIBILITY IDEOGRAPH-FAA5;Lo;0;L;761F;;;;N;;;;; +FAA6;CJK COMPATIBILITY IDEOGRAPH-FAA6;Lo;0;L;76CA;;;;N;;;;; +FAA7;CJK COMPATIBILITY IDEOGRAPH-FAA7;Lo;0;L;76DB;;;;N;;;;; +FAA8;CJK COMPATIBILITY IDEOGRAPH-FAA8;Lo;0;L;76F4;;;;N;;;;; +FAA9;CJK COMPATIBILITY IDEOGRAPH-FAA9;Lo;0;L;774A;;;;N;;;;; +FAAA;CJK COMPATIBILITY IDEOGRAPH-FAAA;Lo;0;L;7740;;;;N;;;;; +FAAB;CJK COMPATIBILITY IDEOGRAPH-FAAB;Lo;0;L;78CC;;;;N;;;;; +FAAC;CJK COMPATIBILITY IDEOGRAPH-FAAC;Lo;0;L;7AB1;;;;N;;;;; +FAAD;CJK COMPATIBILITY IDEOGRAPH-FAAD;Lo;0;L;7BC0;;;;N;;;;; +FAAE;CJK COMPATIBILITY IDEOGRAPH-FAAE;Lo;0;L;7C7B;;;;N;;;;; +FAAF;CJK COMPATIBILITY IDEOGRAPH-FAAF;Lo;0;L;7D5B;;;;N;;;;; +FAB0;CJK COMPATIBILITY IDEOGRAPH-FAB0;Lo;0;L;7DF4;;;;N;;;;; +FAB1;CJK COMPATIBILITY IDEOGRAPH-FAB1;Lo;0;L;7F3E;;;;N;;;;; +FAB2;CJK COMPATIBILITY IDEOGRAPH-FAB2;Lo;0;L;8005;;;;N;;;;; +FAB3;CJK COMPATIBILITY IDEOGRAPH-FAB3;Lo;0;L;8352;;;;N;;;;; +FAB4;CJK COMPATIBILITY IDEOGRAPH-FAB4;Lo;0;L;83EF;;;;N;;;;; +FAB5;CJK COMPATIBILITY IDEOGRAPH-FAB5;Lo;0;L;8779;;;;N;;;;; +FAB6;CJK COMPATIBILITY IDEOGRAPH-FAB6;Lo;0;L;8941;;;;N;;;;; +FAB7;CJK COMPATIBILITY IDEOGRAPH-FAB7;Lo;0;L;8986;;;;N;;;;; +FAB8;CJK COMPATIBILITY IDEOGRAPH-FAB8;Lo;0;L;8996;;;;N;;;;; +FAB9;CJK COMPATIBILITY IDEOGRAPH-FAB9;Lo;0;L;8ABF;;;;N;;;;; +FABA;CJK COMPATIBILITY IDEOGRAPH-FABA;Lo;0;L;8AF8;;;;N;;;;; +FABB;CJK COMPATIBILITY IDEOGRAPH-FABB;Lo;0;L;8ACB;;;;N;;;;; +FABC;CJK COMPATIBILITY IDEOGRAPH-FABC;Lo;0;L;8B01;;;;N;;;;; +FABD;CJK COMPATIBILITY IDEOGRAPH-FABD;Lo;0;L;8AFE;;;;N;;;;; +FABE;CJK COMPATIBILITY IDEOGRAPH-FABE;Lo;0;L;8AED;;;;N;;;;; +FABF;CJK COMPATIBILITY IDEOGRAPH-FABF;Lo;0;L;8B39;;;;N;;;;; +FAC0;CJK COMPATIBILITY IDEOGRAPH-FAC0;Lo;0;L;8B8A;;;;N;;;;; +FAC1;CJK COMPATIBILITY IDEOGRAPH-FAC1;Lo;0;L;8D08;;;;N;;;;; +FAC2;CJK COMPATIBILITY IDEOGRAPH-FAC2;Lo;0;L;8F38;;;;N;;;;; +FAC3;CJK COMPATIBILITY IDEOGRAPH-FAC3;Lo;0;L;9072;;;;N;;;;; +FAC4;CJK COMPATIBILITY IDEOGRAPH-FAC4;Lo;0;L;9199;;;;N;;;;; +FAC5;CJK COMPATIBILITY IDEOGRAPH-FAC5;Lo;0;L;9276;;;;N;;;;; +FAC6;CJK COMPATIBILITY IDEOGRAPH-FAC6;Lo;0;L;967C;;;;N;;;;; +FAC7;CJK COMPATIBILITY IDEOGRAPH-FAC7;Lo;0;L;96E3;;;;N;;;;; +FAC8;CJK COMPATIBILITY IDEOGRAPH-FAC8;Lo;0;L;9756;;;;N;;;;; +FAC9;CJK COMPATIBILITY IDEOGRAPH-FAC9;Lo;0;L;97DB;;;;N;;;;; +FACA;CJK COMPATIBILITY IDEOGRAPH-FACA;Lo;0;L;97FF;;;;N;;;;; +FACB;CJK COMPATIBILITY IDEOGRAPH-FACB;Lo;0;L;980B;;;;N;;;;; +FACC;CJK COMPATIBILITY IDEOGRAPH-FACC;Lo;0;L;983B;;;;N;;;;; +FACD;CJK COMPATIBILITY IDEOGRAPH-FACD;Lo;0;L;9B12;;;;N;;;;; +FACE;CJK COMPATIBILITY IDEOGRAPH-FACE;Lo;0;L;9F9C;;;;N;;;;; +FACF;CJK COMPATIBILITY IDEOGRAPH-FACF;Lo;0;L;2284A;;;;N;;;;; +FAD0;CJK COMPATIBILITY IDEOGRAPH-FAD0;Lo;0;L;22844;;;;N;;;;; +FAD1;CJK COMPATIBILITY IDEOGRAPH-FAD1;Lo;0;L;233D5;;;;N;;;;; +FAD2;CJK COMPATIBILITY IDEOGRAPH-FAD2;Lo;0;L;3B9D;;;;N;;;;; +FAD3;CJK COMPATIBILITY IDEOGRAPH-FAD3;Lo;0;L;4018;;;;N;;;;; +FAD4;CJK COMPATIBILITY IDEOGRAPH-FAD4;Lo;0;L;4039;;;;N;;;;; +FAD5;CJK COMPATIBILITY IDEOGRAPH-FAD5;Lo;0;L;25249;;;;N;;;;; +FAD6;CJK COMPATIBILITY IDEOGRAPH-FAD6;Lo;0;L;25CD0;;;;N;;;;; +FAD7;CJK COMPATIBILITY IDEOGRAPH-FAD7;Lo;0;L;27ED3;;;;N;;;;; +FAD8;CJK COMPATIBILITY IDEOGRAPH-FAD8;Lo;0;L;9F43;;;;N;;;;; +FAD9;CJK COMPATIBILITY IDEOGRAPH-FAD9;Lo;0;L;9F8E;;;;N;;;;; +FB00;LATIN SMALL LIGATURE FF;Ll;0;L; 0066 0066;;;;N;;;;; +FB01;LATIN SMALL LIGATURE FI;Ll;0;L; 0066 0069;;;;N;;;;; +FB02;LATIN SMALL LIGATURE FL;Ll;0;L; 0066 006C;;;;N;;;;; +FB03;LATIN SMALL LIGATURE FFI;Ll;0;L; 0066 0066 0069;;;;N;;;;; +FB04;LATIN SMALL LIGATURE FFL;Ll;0;L; 0066 0066 006C;;;;N;;;;; +FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L; 017F 0074;;;;N;;;;; +FB06;LATIN SMALL LIGATURE ST;Ll;0;L; 0073 0074;;;;N;;;;; +FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L; 0574 0576;;;;N;;;;; +FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L; 0574 0565;;;;N;;;;; +FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L; 0574 056B;;;;N;;;;; +FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L; 057E 0576;;;;N;;;;; +FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L; 0574 056D;;;;N;;;;; +FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;; +FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;; +FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;; +FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R; 05E2;;;;N;;;;; +FB21;HEBREW LETTER WIDE ALEF;Lo;0;R; 05D0;;;;N;;;;; +FB22;HEBREW LETTER WIDE DALET;Lo;0;R; 05D3;;;;N;;;;; +FB23;HEBREW LETTER WIDE HE;Lo;0;R; 05D4;;;;N;;;;; +FB24;HEBREW LETTER WIDE KAF;Lo;0;R; 05DB;;;;N;;;;; +FB25;HEBREW LETTER WIDE LAMED;Lo;0;R; 05DC;;;;N;;;;; +FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R; 05DD;;;;N;;;;; +FB27;HEBREW LETTER WIDE RESH;Lo;0;R; 05E8;;;;N;;;;; +FB28;HEBREW LETTER WIDE TAV;Lo;0;R; 05EA;;;;N;;;;; +FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;; +FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;; +FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;; +FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;; +FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;; +FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;; +FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;; +FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;; +FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;; +FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;; +FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;; +FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;; +FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;; +FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;; +FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;; +FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;; +FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;; +FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;; +FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;; +FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;; +FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;; +FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;; +FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;; +FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;; +FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;; +FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;; +FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;; +FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;; +FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;; +FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;; +FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;; +FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;; +FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R; 05D0 05DC;;;;N;;;;; +FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL; 0671;;;;N;;;;; +FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL; 0671;;;;N;;;;; +FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL; 067B;;;;N;;;;; +FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL; 067E;;;;N;;;;; +FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL; 067A;;;;N;;;;; +FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL; 067F;;;;N;;;;; +FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL; 0679;;;;N;;;;; +FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL; 0684;;;;N;;;;; +FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL; 0683;;;;N;;;;; +FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL; 0687;;;;N;;;;; +FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL; 068D;;;;N;;;;; +FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL; 068D;;;;N;;;;; +FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL; 068C;;;;N;;;;; +FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL; 068C;;;;N;;;;; +FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL; 068E;;;;N;;;;; +FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL; 068E;;;;N;;;;; +FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL; 0688;;;;N;;;;; +FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL; 0688;;;;N;;;;; +FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL; 06BA;;;;N;;;;; +FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL; 06BA;;;;N;;;;; +FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0677;;;;N;;;;; +FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062B 062C;;;;N;;;;; +FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL; 062E 062D;;;;N;;;;; +FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0645 0649;;;;N;;;;; +FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL; 0645 064A;;;;N;;;;; +FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0647 0649;;;;N;;;;; +FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL; 0647 064A;;;;N;;;;; +FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0630 0670;;;;N;;;;; +FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0631 0670;;;;N;;;;; +FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C 0651;;;;N;;;;; +FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D 0651;;;;N;;;;; +FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL; 0020 064E 0651;;;;N;;;;; +FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F 0651;;;;N;;;;; +FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL; 0020 0650 0651;;;;N;;;;; +FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0020 0651 0670;;;;N;;;;; +FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL; 0626 0631;;;;N;;;;; +FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL; 0626 0632;;;;N;;;;; +FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL; 0626 0646;;;;N;;;;; +FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL; 0628 0631;;;;N;;;;; +FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL; 0628 0632;;;;N;;;;; +FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL; 0628 0646;;;;N;;;;; +FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL; 062A 0631;;;;N;;;;; +FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL; 062A 0632;;;;N;;;;; +FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL; 062A 0646;;;;N;;;;; +FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL; 062B 0631;;;;N;;;;; +FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL; 062B 0632;;;;N;;;;; +FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL; 062B 0646;;;;N;;;;; +FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL; 0645 0627;;;;N;;;;; +FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL; 0646 0631;;;;N;;;;; +FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL; 0646 0632;;;;N;;;;; +FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL; 0646 0646;;;;N;;;;; +FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL; 064A 0631;;;;N;;;;; +FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL; 064A 0632;;;;N;;;;; +FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL; 064A 0646;;;;N;;;;; +FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL; 0626 062E;;;;N;;;;; +FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL; 0635 062E;;;;N;;;;; +FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL; 0644 0647;;;;N;;;;; +FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL; 0647 0670;;;;N;;;;; +FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL; 062B 0647;;;;N;;;;; +FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL; 0640 064E 0651;;;;N;;;;; +FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F 0651;;;;N;;;;; +FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL; 0640 0650 0651;;;;N;;;;; +FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;; +FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;; +FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062C 0645;;;;N;;;;; +FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062D 0645;;;;N;;;;; +FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062E 0645;;;;N;;;;; +FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 062A 0645 062C;;;;N;;;;; +FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062A 0645 062D;;;;N;;;;; +FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 062A 0645 062E;;;;N;;;;; +FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 0645 064A;;;;N;;;;; +FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0645 0649;;;;N;;;;; +FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062D 062C;;;;N;;;;; +FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 062C 062D;;;;N;;;;; +FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062C 0649;;;;N;;;;; +FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0633 0645 062C;;;;N;;;;; +FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0634 062C 064A;;;;N;;;;; +FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 062D 0649;;;;N;;;;; +FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645 0645;;;;N;;;;; +FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0637 0645 064A;;;;N;;;;; +FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0645 0649;;;;N;;;;; +FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 063A 0645 0645;;;;N;;;;; +FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 063A 0645 064A;;;;N;;;;; +FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0645 0649;;;;N;;;;; +FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0642 0645 0645;;;;N;;;;; +FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0644 062D 064A;;;;N;;;;; +FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 062D 0649;;;;N;;;;; +FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062D 062C;;;;N;;;;; +FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062D 0645;;;;N;;;;; +FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062D 064A;;;;N;;;;; +FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062C 062D;;;;N;;;;; +FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062C 0645;;;;N;;;;; +FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062E 062C;;;;N;;;;; +FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062E 0645;;;;N;;;;; +FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062C 062E;;;;N;;;;; +FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0647 0645 062C;;;;N;;;;; +FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645 0645;;;;N;;;;; +FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062D 0645;;;;N;;;;; +FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062D 0649;;;;N;;;;; +FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062C 0649;;;;N;;;;; +FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 0645 064A;;;;N;;;;; +FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0645 0649;;;;N;;;;; +FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062E 064A;;;;N;;;;; +FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 062C 064A;;;;N;;;;; +FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062C 0649;;;;N;;;;; +FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 062A 062E 064A;;;;N;;;;; +FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062E 0649;;;;N;;;;; +FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 0645 064A;;;;N;;;;; +FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0645 0649;;;;N;;;;; +FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 0645 064A;;;;N;;;;; +FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 062D 0649;;;;N;;;;; +FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0645 0649;;;;N;;;;; +FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062E 0649;;;;N;;;;; +FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0635 062D 064A;;;;N;;;;; +FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0634 062D 064A;;;;N;;;;; +FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0636 062D 064A;;;;N;;;;; +FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 062C 064A;;;;N;;;;; +FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 0645 064A;;;;N;;;;; +FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 064A 062D 064A;;;;N;;;;; +FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 062C 064A;;;;N;;;;; +FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 0645 064A;;;;N;;;;; +FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 0645 064A;;;;N;;;;; +FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0642 0645 064A;;;;N;;;;; +FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0646 062D 064A;;;;N;;;;; +FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0639 0645 064A;;;;N;;;;; +FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0643 0645 064A;;;;N;;;;; +FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062E 064A;;;;N;;;;; +FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 062C 062D 064A;;;;N;;;;; +FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 062C 064A;;;;N;;;;; +FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 062C 064A;;;;N;;;;; +FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0641 0645 064A;;;;N;;;;; +FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062D 064A;;;;N;;;;; +FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0633 062E 064A;;;;N;;;;; +FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 062C 064A;;;;N;;;;; +FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0635 0644 06D2;;;;N;;;;; +FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0642 0644 06D2;;;;N;;;;; +FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL; 0627 0644 0644 0647;;;;N;;;;; +FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL; 0627 0643 0628 0631;;;;N;;;;; +FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL; 0645 062D 0645 062F;;;;N;;;;; +FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL; 0635 0644 0639 0645;;;;N;;;;; +FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL; 0631 0633 0648 0644;;;;N;;;;; +FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL; 0639 0644 064A 0647;;;;N;;;;; +FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL; 0648 0633 0644 0645;;;;N;;;;; +FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL; 0635 0644 0649;;;;N;;;;; +FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL; 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;; +FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL; 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;; +FDFC;RIAL SIGN;Sc;0;AL; 0631 06CC 0627 0644;;;;N;;;;; +FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;; +FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;; +FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;; +FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;; +FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;; +FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;; +FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;; +FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;; +FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;; +FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;; +FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;; +FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;; +FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;; +FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;; +FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;; +FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;; +FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;; +FE10;PRESENTATION FORM FOR VERTICAL COMMA;Po;0;ON; 002C;;;;N;;;;; +FE11;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FE12;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;;;;; +FE13;PRESENTATION FORM FOR VERTICAL COLON;Po;0;ON; 003A;;;;N;;;;; +FE14;PRESENTATION FORM FOR VERTICAL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FE15;PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FE16;PRESENTATION FORM FOR VERTICAL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps;0;ON; 3016;;;;N;;;;; +FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe;0;ON; 3017;;;;N;;;;; +FE19;PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS;Po;0;ON; 2026;;;;N;;;;; +FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;; +FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON; 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;; +FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON; 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;; +FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON; 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;; +FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;; +FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;; +FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;; +FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;; +FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;; +FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;; +FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;; +FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;; +FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON; 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;; +FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON; 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;; +FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON; 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;; +FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON; 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;; +FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON; 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;; +FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON; 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;; +FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;; +FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;; +FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON; 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;; +FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON; 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;; +FE45;SESAME DOT;Po;0;ON;;;;;N;;;;; +FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;; +FE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;N;;;;; +FE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;N;;;;; +FE49;DASHED OVERLINE;Po;0;ON; 203E;;;;N;SPACING DASHED OVERSCORE;;;; +FE4A;CENTRELINE OVERLINE;Po;0;ON; 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;; +FE4B;WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING WAVY OVERSCORE;;;; +FE4C;DOUBLE WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;; +FE4D;DASHED LOW LINE;Pc;0;ON; 005F;;;;N;SPACING DASHED UNDERSCORE;;;; +FE4E;CENTRELINE LOW LINE;Pc;0;ON; 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;; +FE4F;WAVY LOW LINE;Pc;0;ON; 005F;;;;N;SPACING WAVY UNDERSCORE;;;; +FE50;SMALL COMMA;Po;0;CS; 002C;;;;N;;;;; +FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FE52;SMALL FULL STOP;Po;0;CS; 002E;;;;N;SMALL PERIOD;;;; +FE54;SMALL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FE55;SMALL COLON;Po;0;CS; 003A;;;;N;;;;; +FE56;SMALL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FE57;SMALL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FE58;SMALL EM DASH;Pd;0;ON; 2014;;;;N;;;;; +FE59;SMALL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SMALL OPENING PARENTHESIS;;;; +FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SMALL CLOSING PARENTHESIS;;;; +FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;SMALL OPENING CURLY BRACKET;;;; +FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;SMALL CLOSING CURLY BRACKET;;;; +FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;Y;SMALL OPENING TORTOISE SHELL BRACKET;;;; +FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;Y;SMALL CLOSING TORTOISE SHELL BRACKET;;;; +FE5F;SMALL NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FE60;SMALL AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FE61;SMALL ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FE62;SMALL PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FE63;SMALL HYPHEN-MINUS;Pd;0;ES; 002D;;;;N;;;;; +FE64;SMALL LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; +FE65;SMALL GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; +FE66;SMALL EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FE68;SMALL REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;SMALL BACKSLASH;;;; +FE69;SMALL DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FE6A;SMALL PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FE6B;SMALL COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL; 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;; +FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL; 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;; +FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;; +FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;; +FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;; +FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL; 0020 064E;;;;N;ARABIC SPACING FATHAH;;;; +FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL; 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;; +FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;; +FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;; +FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL; 0020 0650;;;;N;ARABIC SPACING KASRAH;;;; +FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL; 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;; +FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL; 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;; +FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL; 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;; +FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL; 0020 0652;;;;N;ARABIC SPACING SUKUN;;;; +FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL; 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;; +FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL; 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;; +FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;; +FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;; +FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;; +FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;; +FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;; +FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;; +FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;; +FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;; +FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;; +FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;; +FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;; +FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;; +FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;; +FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;; +FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;; +FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;; +FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;; +FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;; +FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;; +FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;; +FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;; +FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;; +FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;; +FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;; +FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;; +FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;; +FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;; +FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;; +FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;; +FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;; +FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;; +FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;; +FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;; +FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;; +FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;; +FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;; +FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;; +FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;; +FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;; +FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;; +FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;; +FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;; +FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;; +FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;; +FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;; +FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;; +FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;; +FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;; +FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;; +FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;; +FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;; +FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;; +FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;; +FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;; +FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;; +FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;; +FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;; +FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;; +FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;; +FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;; +FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;; +FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;; +FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;; +FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;; +FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;; +FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;; +FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;; +FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;; +FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;; +FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;; +FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;; +FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;; +FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;; +FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;; +FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;; +FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;; +FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;; +FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;; +FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;; +FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;; +FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;; +FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;; +FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;; +FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;; +FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;; +FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;; +FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;; +FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;; +FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;; +FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;; +FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;; +FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;; +FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;; +FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;; +FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;; +FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;; +FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;; +FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;; +FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;; +FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;; +FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;; +FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;; +FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;; +FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;; +FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;; +FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;; +FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;; +FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;; +FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;; +FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;; +FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;; +FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;; +FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;; +FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;; +FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;; +FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;; +FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;; +FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;; +FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; +FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FF02;FULLWIDTH QUOTATION MARK;Po;0;ON; 0022;;;;N;;;;; +FF03;FULLWIDTH NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FF05;FULLWIDTH PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FF06;FULLWIDTH AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FF07;FULLWIDTH APOSTROPHE;Po;0;ON; 0027;;;;N;;;;; +FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;; +FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;; +FF0A;FULLWIDTH ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FF0B;FULLWIDTH PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FF0C;FULLWIDTH COMMA;Po;0;CS; 002C;;;;N;;;;; +FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ES; 002D;;;;N;;;;; +FF0E;FULLWIDTH FULL STOP;Po;0;CS; 002E;;;;N;FULLWIDTH PERIOD;;;; +FF0F;FULLWIDTH SOLIDUS;Po;0;CS; 002F;;;;N;FULLWIDTH SLASH;;;; +FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +FF11;FULLWIDTH DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +FF12;FULLWIDTH DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +FF13;FULLWIDTH DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +FF16;FULLWIDTH DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +FF19;FULLWIDTH DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +FF1A;FULLWIDTH COLON;Po;0;CS; 003A;;;;N;;;;; +FF1B;FULLWIDTH SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; +FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; +FF1F;FULLWIDTH QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L; 0041;;;;N;;;;FF41; +FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L; 0042;;;;N;;;;FF42; +FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L; 0043;;;;N;;;;FF43; +FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L; 0044;;;;N;;;;FF44; +FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L; 0045;;;;N;;;;FF45; +FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L; 0046;;;;N;;;;FF46; +FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L; 0047;;;;N;;;;FF47; +FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L; 0048;;;;N;;;;FF48; +FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L; 0049;;;;N;;;;FF49; +FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L; 004A;;;;N;;;;FF4A; +FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L; 004B;;;;N;;;;FF4B; +FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L; 004C;;;;N;;;;FF4C; +FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L; 004D;;;;N;;;;FF4D; +FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L; 004E;;;;N;;;;FF4E; +FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L; 004F;;;;N;;;;FF4F; +FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L; 0050;;;;N;;;;FF50; +FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L; 0051;;;;N;;;;FF51; +FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L; 0052;;;;N;;;;FF52; +FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L; 0053;;;;N;;;;FF53; +FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L; 0054;;;;N;;;;FF54; +FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L; 0055;;;;N;;;;FF55; +FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L; 0056;;;;N;;;;FF56; +FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L; 0057;;;;N;;;;FF57; +FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L; 0058;;;;N;;;;FF58; +FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L; 0059;;;;N;;;;FF59; +FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L; 005A;;;;N;;;;FF5A; +FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;; +FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;FULLWIDTH BACKSLASH;;;; +FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;; +FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON; 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;; +FF3F;FULLWIDTH LOW LINE;Pc;0;ON; 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;; +FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON; 0060;;;;N;FULLWIDTH SPACING GRAVE;;;; +FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L; 0061;;;;N;;;FF21;;FF21 +FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L; 0062;;;;N;;;FF22;;FF22 +FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L; 0063;;;;N;;;FF23;;FF23 +FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L; 0064;;;;N;;;FF24;;FF24 +FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L; 0065;;;;N;;;FF25;;FF25 +FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L; 0066;;;;N;;;FF26;;FF26 +FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L; 0067;;;;N;;;FF27;;FF27 +FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L; 0068;;;;N;;;FF28;;FF28 +FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;FF29;;FF29 +FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L; 006A;;;;N;;;FF2A;;FF2A +FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L; 006B;;;;N;;;FF2B;;FF2B +FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L; 006C;;;;N;;;FF2C;;FF2C +FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L; 006D;;;;N;;;FF2D;;FF2D +FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;FF2E;;FF2E +FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L; 006F;;;;N;;;FF2F;;FF2F +FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L; 0070;;;;N;;;FF30;;FF30 +FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L; 0071;;;;N;;;FF31;;FF31 +FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L; 0072;;;;N;;;FF32;;FF32 +FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L; 0073;;;;N;;;FF33;;FF33 +FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L; 0074;;;;N;;;FF34;;FF34 +FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L; 0075;;;;N;;;FF35;;FF35 +FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L; 0076;;;;N;;;FF36;;FF36 +FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L; 0077;;;;N;;;FF37;;FF37 +FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L; 0078;;;;N;;;FF38;;FF38 +FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L; 0079;;;;N;;;FF39;;FF39 +FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L; 007A;;;;N;;;FF3A;;FF3A +FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;; +FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON; 007C;;;;N;FULLWIDTH VERTICAL BAR;;;; +FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;; +FF5E;FULLWIDTH TILDE;Sm;0;ON; 007E;;;;N;FULLWIDTH SPACING TILDE;;;; +FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON; 2985;;;;Y;;*;;; +FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON; 2986;;;;Y;;*;;; +FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;; +FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;; +FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;; +FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FF65;HALFWIDTH KATAKANA MIDDLE DOT;Po;0;ON; 30FB;;;;N;;;;; +FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L; 30F2;;;;N;;;;; +FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L; 30A1;;;;N;;;;; +FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L; 30A3;;;;N;;;;; +FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L; 30A5;;;;N;;;;; +FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L; 30A7;;;;N;;;;; +FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L; 30A9;;;;N;;;;; +FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L; 30E3;;;;N;;;;; +FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L; 30E5;;;;N;;;;; +FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L; 30E7;;;;N;;;;; +FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L; 30C3;;;;N;;;;; +FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L; 30FC;;;;N;;;;; +FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L; 30A2;;;;N;;;;; +FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L; 30A4;;;;N;;;;; +FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L; 30A6;;;;N;;;;; +FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L; 30A8;;;;N;;;;; +FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L; 30AA;;;;N;;;;; +FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L; 30AB;;;;N;;;;; +FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L; 30AD;;;;N;;;;; +FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L; 30AF;;;;N;;;;; +FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L; 30B1;;;;N;;;;; +FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L; 30B3;;;;N;;;;; +FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L; 30B5;;;;N;;;;; +FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L; 30B7;;;;N;;;;; +FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L; 30B9;;;;N;;;;; +FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L; 30BB;;;;N;;;;; +FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L; 30BD;;;;N;;;;; +FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L; 30BF;;;;N;;;;; +FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L; 30C1;;;;N;;;;; +FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L; 30C4;;;;N;;;;; +FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L; 30C6;;;;N;;;;; +FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L; 30C8;;;;N;;;;; +FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L; 30CA;;;;N;;;;; +FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L; 30CB;;;;N;;;;; +FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L; 30CC;;;;N;;;;; +FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L; 30CD;;;;N;;;;; +FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L; 30CE;;;;N;;;;; +FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L; 30CF;;;;N;;;;; +FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L; 30D2;;;;N;;;;; +FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L; 30D5;;;;N;;;;; +FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L; 30D8;;;;N;;;;; +FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L; 30DB;;;;N;;;;; +FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L; 30DE;;;;N;;;;; +FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L; 30DF;;;;N;;;;; +FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L; 30E0;;;;N;;;;; +FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L; 30E1;;;;N;;;;; +FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L; 30E2;;;;N;;;;; +FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L; 30E4;;;;N;;;;; +FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L; 30E6;;;;N;;;;; +FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L; 30E8;;;;N;;;;; +FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L; 30E9;;;;N;;;;; +FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L; 30EA;;;;N;;;;; +FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L; 30EB;;;;N;;;;; +FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L; 30EC;;;;N;;;;; +FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L; 30ED;;;;N;;;;; +FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L; 30EF;;;;N;;;;; +FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L; 30F3;;;;N;;;;; +FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L; 3099;;;;N;;halfwidth katakana-hiragana voiced sound mark;;; +FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L; 309A;;;;N;;halfwidth katakana-hiragana semi-voiced sound mark;;; +FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L; 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;; +FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L; 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;; +FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L; 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;; +FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;; +FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L; 3134;;;;N;;;;; +FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;; +FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;; +FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L; 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;; +FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L; 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;; +FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L; 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;; +FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;; +FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;; +FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;; +FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L; 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;; +FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;; +FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;; +FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;; +FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L; 3141;;;;N;;;;; +FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L; 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;; +FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L; 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;; +FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L; 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;; +FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L; 3145;;;;N;;;;; +FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L; 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;; +FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L; 3147;;;;N;;;;; +FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L; 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;; +FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L; 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;; +FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L; 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;; +FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L; 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;; +FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L; 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;; +FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L; 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;; +FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L; 314E;;;;N;;;;; +FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L; 314F;;;;N;;;;; +FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L; 3150;;;;N;;;;; +FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L; 3151;;;;N;;;;; +FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L; 3152;;;;N;;;;; +FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L; 3153;;;;N;;;;; +FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L; 3154;;;;N;;;;; +FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L; 3155;;;;N;;;;; +FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L; 3156;;;;N;;;;; +FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L; 3157;;;;N;;;;; +FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L; 3158;;;;N;;;;; +FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L; 3159;;;;N;;;;; +FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L; 315A;;;;N;;;;; +FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L; 315B;;;;N;;;;; +FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L; 315C;;;;N;;;;; +FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L; 315D;;;;N;;;;; +FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L; 315E;;;;N;;;;; +FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L; 315F;;;;N;;;;; +FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L; 3160;;;;N;;;;; +FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L; 3161;;;;N;;;;; +FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L; 3162;;;;N;;;;; +FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L; 3163;;;;N;;;;; +FFE0;FULLWIDTH CENT SIGN;Sc;0;ET; 00A2;;;;N;;;;; +FFE1;FULLWIDTH POUND SIGN;Sc;0;ET; 00A3;;;;N;;;;; +FFE2;FULLWIDTH NOT SIGN;Sm;0;ON; 00AC;;;;N;;;;; +FFE3;FULLWIDTH MACRON;Sk;0;ON; 00AF;;;;N;FULLWIDTH SPACING MACRON;*;;; +FFE4;FULLWIDTH BROKEN BAR;So;0;ON; 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;; +FFE5;FULLWIDTH YEN SIGN;Sc;0;ET; 00A5;;;;N;;;;; +FFE6;FULLWIDTH WON SIGN;Sc;0;ET; 20A9;;;;N;;;;; +FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON; 2502;;;;N;;;;; +FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON; 2190;;;;N;;;;; +FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON; 2191;;;;N;;;;; +FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON; 2192;;;;N;;;;; +FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON; 2193;;;;N;;;;; +FFED;HALFWIDTH BLACK SQUARE;So;0;ON; 25A0;;;;N;;;;; +FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON; 25CB;;;;N;;;;; +FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;ON;;;;;N;;;;; +FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;ON;;;;;N;;;;; +FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;ON;;;;;N;;;;; +FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +10000;LINEAR B SYLLABLE B008 A;Lo;0;L;;;;;N;;;;; +10001;LINEAR B SYLLABLE B038 E;Lo;0;L;;;;;N;;;;; +10002;LINEAR B SYLLABLE B028 I;Lo;0;L;;;;;N;;;;; +10003;LINEAR B SYLLABLE B061 O;Lo;0;L;;;;;N;;;;; +10004;LINEAR B SYLLABLE B010 U;Lo;0;L;;;;;N;;;;; +10005;LINEAR B SYLLABLE B001 DA;Lo;0;L;;;;;N;;;;; +10006;LINEAR B SYLLABLE B045 DE;Lo;0;L;;;;;N;;;;; +10007;LINEAR B SYLLABLE B007 DI;Lo;0;L;;;;;N;;;;; +10008;LINEAR B SYLLABLE B014 DO;Lo;0;L;;;;;N;;;;; +10009;LINEAR B SYLLABLE B051 DU;Lo;0;L;;;;;N;;;;; +1000A;LINEAR B SYLLABLE B057 JA;Lo;0;L;;;;;N;;;;; +1000B;LINEAR B SYLLABLE B046 JE;Lo;0;L;;;;;N;;;;; +1000D;LINEAR B SYLLABLE B036 JO;Lo;0;L;;;;;N;;;;; +1000E;LINEAR B SYLLABLE B065 JU;Lo;0;L;;;;;N;;;;; +1000F;LINEAR B SYLLABLE B077 KA;Lo;0;L;;;;;N;;;;; +10010;LINEAR B SYLLABLE B044 KE;Lo;0;L;;;;;N;;;;; +10011;LINEAR B SYLLABLE B067 KI;Lo;0;L;;;;;N;;;;; +10012;LINEAR B SYLLABLE B070 KO;Lo;0;L;;;;;N;;;;; +10013;LINEAR B SYLLABLE B081 KU;Lo;0;L;;;;;N;;;;; +10014;LINEAR B SYLLABLE B080 MA;Lo;0;L;;;;;N;;;;; +10015;LINEAR B SYLLABLE B013 ME;Lo;0;L;;;;;N;;;;; +10016;LINEAR B SYLLABLE B073 MI;Lo;0;L;;;;;N;;;;; +10017;LINEAR B SYLLABLE B015 MO;Lo;0;L;;;;;N;;;;; +10018;LINEAR B SYLLABLE B023 MU;Lo;0;L;;;;;N;;;;; +10019;LINEAR B SYLLABLE B006 NA;Lo;0;L;;;;;N;;;;; +1001A;LINEAR B SYLLABLE B024 NE;Lo;0;L;;;;;N;;;;; +1001B;LINEAR B SYLLABLE B030 NI;Lo;0;L;;;;;N;;;;; +1001C;LINEAR B SYLLABLE B052 NO;Lo;0;L;;;;;N;;;;; +1001D;LINEAR B SYLLABLE B055 NU;Lo;0;L;;;;;N;;;;; +1001E;LINEAR B SYLLABLE B003 PA;Lo;0;L;;;;;N;;;;; +1001F;LINEAR B SYLLABLE B072 PE;Lo;0;L;;;;;N;;;;; +10020;LINEAR B SYLLABLE B039 PI;Lo;0;L;;;;;N;;;;; +10021;LINEAR B SYLLABLE B011 PO;Lo;0;L;;;;;N;;;;; +10022;LINEAR B SYLLABLE B050 PU;Lo;0;L;;;;;N;;;;; +10023;LINEAR B SYLLABLE B016 QA;Lo;0;L;;;;;N;;;;; +10024;LINEAR B SYLLABLE B078 QE;Lo;0;L;;;;;N;;;;; +10025;LINEAR B SYLLABLE B021 QI;Lo;0;L;;;;;N;;;;; +10026;LINEAR B SYLLABLE B032 QO;Lo;0;L;;;;;N;;;;; +10028;LINEAR B SYLLABLE B060 RA;Lo;0;L;;;;;N;;;;; +10029;LINEAR B SYLLABLE B027 RE;Lo;0;L;;;;;N;;;;; +1002A;LINEAR B SYLLABLE B053 RI;Lo;0;L;;;;;N;;;;; +1002B;LINEAR B SYLLABLE B002 RO;Lo;0;L;;;;;N;;;;; +1002C;LINEAR B SYLLABLE B026 RU;Lo;0;L;;;;;N;;;;; +1002D;LINEAR B SYLLABLE B031 SA;Lo;0;L;;;;;N;;;;; +1002E;LINEAR B SYLLABLE B009 SE;Lo;0;L;;;;;N;;;;; +1002F;LINEAR B SYLLABLE B041 SI;Lo;0;L;;;;;N;;;;; +10030;LINEAR B SYLLABLE B012 SO;Lo;0;L;;;;;N;;;;; +10031;LINEAR B SYLLABLE B058 SU;Lo;0;L;;;;;N;;;;; +10032;LINEAR B SYLLABLE B059 TA;Lo;0;L;;;;;N;;;;; +10033;LINEAR B SYLLABLE B004 TE;Lo;0;L;;;;;N;;;;; +10034;LINEAR B SYLLABLE B037 TI;Lo;0;L;;;;;N;;;;; +10035;LINEAR B SYLLABLE B005 TO;Lo;0;L;;;;;N;;;;; +10036;LINEAR B SYLLABLE B069 TU;Lo;0;L;;;;;N;;;;; +10037;LINEAR B SYLLABLE B054 WA;Lo;0;L;;;;;N;;;;; +10038;LINEAR B SYLLABLE B075 WE;Lo;0;L;;;;;N;;;;; +10039;LINEAR B SYLLABLE B040 WI;Lo;0;L;;;;;N;;;;; +1003A;LINEAR B SYLLABLE B042 WO;Lo;0;L;;;;;N;;;;; +1003C;LINEAR B SYLLABLE B017 ZA;Lo;0;L;;;;;N;;;;; +1003D;LINEAR B SYLLABLE B074 ZE;Lo;0;L;;;;;N;;;;; +1003F;LINEAR B SYLLABLE B020 ZO;Lo;0;L;;;;;N;;;;; +10040;LINEAR B SYLLABLE B025 A2;Lo;0;L;;;;;N;;;;; +10041;LINEAR B SYLLABLE B043 A3;Lo;0;L;;;;;N;;;;; +10042;LINEAR B SYLLABLE B085 AU;Lo;0;L;;;;;N;;;;; +10043;LINEAR B SYLLABLE B071 DWE;Lo;0;L;;;;;N;;;;; +10044;LINEAR B SYLLABLE B090 DWO;Lo;0;L;;;;;N;;;;; +10045;LINEAR B SYLLABLE B048 NWA;Lo;0;L;;;;;N;;;;; +10046;LINEAR B SYLLABLE B029 PU2;Lo;0;L;;;;;N;;;;; +10047;LINEAR B SYLLABLE B062 PTE;Lo;0;L;;;;;N;;;;; +10048;LINEAR B SYLLABLE B076 RA2;Lo;0;L;;;;;N;;;;; +10049;LINEAR B SYLLABLE B033 RA3;Lo;0;L;;;;;N;;;;; +1004A;LINEAR B SYLLABLE B068 RO2;Lo;0;L;;;;;N;;;;; +1004B;LINEAR B SYLLABLE B066 TA2;Lo;0;L;;;;;N;;;;; +1004C;LINEAR B SYLLABLE B087 TWE;Lo;0;L;;;;;N;;;;; +1004D;LINEAR B SYLLABLE B091 TWO;Lo;0;L;;;;;N;;;;; +10050;LINEAR B SYMBOL B018;Lo;0;L;;;;;N;;;;; +10051;LINEAR B SYMBOL B019;Lo;0;L;;;;;N;;;;; +10052;LINEAR B SYMBOL B022;Lo;0;L;;;;;N;;;;; +10053;LINEAR B SYMBOL B034;Lo;0;L;;;;;N;;;;; +10054;LINEAR B SYMBOL B047;Lo;0;L;;;;;N;;;;; +10055;LINEAR B SYMBOL B049;Lo;0;L;;;;;N;;;;; +10056;LINEAR B SYMBOL B056;Lo;0;L;;;;;N;;;;; +10057;LINEAR B SYMBOL B063;Lo;0;L;;;;;N;;;;; +10058;LINEAR B SYMBOL B064;Lo;0;L;;;;;N;;;;; +10059;LINEAR B SYMBOL B079;Lo;0;L;;;;;N;;;;; +1005A;LINEAR B SYMBOL B082;Lo;0;L;;;;;N;;;;; +1005B;LINEAR B SYMBOL B083;Lo;0;L;;;;;N;;;;; +1005C;LINEAR B SYMBOL B086;Lo;0;L;;;;;N;;;;; +1005D;LINEAR B SYMBOL B089;Lo;0;L;;;;;N;;;;; +10080;LINEAR B IDEOGRAM B100 MAN;Lo;0;L;;;;;N;;;;; +10081;LINEAR B IDEOGRAM B102 WOMAN;Lo;0;L;;;;;N;;;;; +10082;LINEAR B IDEOGRAM B104 DEER;Lo;0;L;;;;;N;;;;; +10083;LINEAR B IDEOGRAM B105 EQUID;Lo;0;L;;;;;N;;;;; +10084;LINEAR B IDEOGRAM B105F MARE;Lo;0;L;;;;;N;;;;; +10085;LINEAR B IDEOGRAM B105M STALLION;Lo;0;L;;;;;N;;;;; +10086;LINEAR B IDEOGRAM B106F EWE;Lo;0;L;;;;;N;;;;; +10087;LINEAR B IDEOGRAM B106M RAM;Lo;0;L;;;;;N;;;;; +10088;LINEAR B IDEOGRAM B107F SHE-GOAT;Lo;0;L;;;;;N;;;;; +10089;LINEAR B IDEOGRAM B107M HE-GOAT;Lo;0;L;;;;;N;;;;; +1008A;LINEAR B IDEOGRAM B108F SOW;Lo;0;L;;;;;N;;;;; +1008B;LINEAR B IDEOGRAM B108M BOAR;Lo;0;L;;;;;N;;;;; +1008C;LINEAR B IDEOGRAM B109F COW;Lo;0;L;;;;;N;;;;; +1008D;LINEAR B IDEOGRAM B109M BULL;Lo;0;L;;;;;N;;;;; +1008E;LINEAR B IDEOGRAM B120 WHEAT;Lo;0;L;;;;;N;;;;; +1008F;LINEAR B IDEOGRAM B121 BARLEY;Lo;0;L;;;;;N;;;;; +10090;LINEAR B IDEOGRAM B122 OLIVE;Lo;0;L;;;;;N;;;;; +10091;LINEAR B IDEOGRAM B123 SPICE;Lo;0;L;;;;;N;;;;; +10092;LINEAR B IDEOGRAM B125 CYPERUS;Lo;0;L;;;;;N;;;;; +10093;LINEAR B MONOGRAM B127 KAPO;Lo;0;L;;;;;N;;;;; +10094;LINEAR B MONOGRAM B128 KANAKO;Lo;0;L;;;;;N;;;;; +10095;LINEAR B IDEOGRAM B130 OIL;Lo;0;L;;;;;N;;;;; +10096;LINEAR B IDEOGRAM B131 WINE;Lo;0;L;;;;;N;;;;; +10097;LINEAR B IDEOGRAM B132;Lo;0;L;;;;;N;;;;; +10098;LINEAR B MONOGRAM B133 AREPA;Lo;0;L;;;;;N;;;;; +10099;LINEAR B MONOGRAM B135 MERI;Lo;0;L;;;;;N;;;;; +1009A;LINEAR B IDEOGRAM B140 BRONZE;Lo;0;L;;;;;N;;;;; +1009B;LINEAR B IDEOGRAM B141 GOLD;Lo;0;L;;;;;N;;;;; +1009C;LINEAR B IDEOGRAM B142;Lo;0;L;;;;;N;;;;; +1009D;LINEAR B IDEOGRAM B145 WOOL;Lo;0;L;;;;;N;;;;; +1009E;LINEAR B IDEOGRAM B146;Lo;0;L;;;;;N;;;;; +1009F;LINEAR B IDEOGRAM B150;Lo;0;L;;;;;N;;;;; +100A0;LINEAR B IDEOGRAM B151 HORN;Lo;0;L;;;;;N;;;;; +100A1;LINEAR B IDEOGRAM B152;Lo;0;L;;;;;N;;;;; +100A2;LINEAR B IDEOGRAM B153;Lo;0;L;;;;;N;;;;; +100A3;LINEAR B IDEOGRAM B154;Lo;0;L;;;;;N;;;;; +100A4;LINEAR B MONOGRAM B156 TURO2;Lo;0;L;;;;;N;;;;; +100A5;LINEAR B IDEOGRAM B157;Lo;0;L;;;;;N;;;;; +100A6;LINEAR B IDEOGRAM B158;Lo;0;L;;;;;N;;;;; +100A7;LINEAR B IDEOGRAM B159 CLOTH;Lo;0;L;;;;;N;;;;; +100A8;LINEAR B IDEOGRAM B160;Lo;0;L;;;;;N;;;;; +100A9;LINEAR B IDEOGRAM B161;Lo;0;L;;;;;N;;;;; +100AA;LINEAR B IDEOGRAM B162 GARMENT;Lo;0;L;;;;;N;;;;; +100AB;LINEAR B IDEOGRAM B163 ARMOUR;Lo;0;L;;;;;N;;;;; +100AC;LINEAR B IDEOGRAM B164;Lo;0;L;;;;;N;;;;; +100AD;LINEAR B IDEOGRAM B165;Lo;0;L;;;;;N;;;;; +100AE;LINEAR B IDEOGRAM B166;Lo;0;L;;;;;N;;;;; +100AF;LINEAR B IDEOGRAM B167;Lo;0;L;;;;;N;;;;; +100B0;LINEAR B IDEOGRAM B168;Lo;0;L;;;;;N;;;;; +100B1;LINEAR B IDEOGRAM B169;Lo;0;L;;;;;N;;;;; +100B2;LINEAR B IDEOGRAM B170;Lo;0;L;;;;;N;;;;; +100B3;LINEAR B IDEOGRAM B171;Lo;0;L;;;;;N;;;;; +100B4;LINEAR B IDEOGRAM B172;Lo;0;L;;;;;N;;;;; +100B5;LINEAR B IDEOGRAM B173 MONTH;Lo;0;L;;;;;N;;;;; +100B6;LINEAR B IDEOGRAM B174;Lo;0;L;;;;;N;;;;; +100B7;LINEAR B IDEOGRAM B176 TREE;Lo;0;L;;;;;N;;;;; +100B8;LINEAR B IDEOGRAM B177;Lo;0;L;;;;;N;;;;; +100B9;LINEAR B IDEOGRAM B178;Lo;0;L;;;;;N;;;;; +100BA;LINEAR B IDEOGRAM B179;Lo;0;L;;;;;N;;;;; +100BB;LINEAR B IDEOGRAM B180;Lo;0;L;;;;;N;;;;; +100BC;LINEAR B IDEOGRAM B181;Lo;0;L;;;;;N;;;;; +100BD;LINEAR B IDEOGRAM B182;Lo;0;L;;;;;N;;;;; +100BE;LINEAR B IDEOGRAM B183;Lo;0;L;;;;;N;;;;; +100BF;LINEAR B IDEOGRAM B184;Lo;0;L;;;;;N;;;;; +100C0;LINEAR B IDEOGRAM B185;Lo;0;L;;;;;N;;;;; +100C1;LINEAR B IDEOGRAM B189;Lo;0;L;;;;;N;;;;; +100C2;LINEAR B IDEOGRAM B190;Lo;0;L;;;;;N;;;;; +100C3;LINEAR B IDEOGRAM B191 HELMET;Lo;0;L;;;;;N;;;;; +100C4;LINEAR B IDEOGRAM B220 FOOTSTOOL;Lo;0;L;;;;;N;;;;; +100C5;LINEAR B IDEOGRAM B225 BATHTUB;Lo;0;L;;;;;N;;;;; +100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;; +100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;; +100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;; +100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;pug;;; +100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;; +100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;gup;;; +100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;; +100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;; +100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;; +100CF;LINEAR B IDEOGRAM B243 WHEEL;Lo;0;L;;;;;N;;;;; +100D0;LINEAR B IDEOGRAM B245;Lo;0;L;;;;;N;;;;; +100D1;LINEAR B IDEOGRAM B246;Lo;0;L;;;;;N;;;;; +100D2;LINEAR B MONOGRAM B247 DIPTE;Lo;0;L;;;;;N;;;;; +100D3;LINEAR B IDEOGRAM B248;Lo;0;L;;;;;N;;;;; +100D4;LINEAR B IDEOGRAM B249;Lo;0;L;;;;;N;;;;; +100D5;LINEAR B IDEOGRAM B251;Lo;0;L;;;;;N;;;;; +100D6;LINEAR B IDEOGRAM B252;Lo;0;L;;;;;N;;;;; +100D7;LINEAR B IDEOGRAM B253;Lo;0;L;;;;;N;;;;; +100D8;LINEAR B IDEOGRAM B254 DART;Lo;0;L;;;;;N;;;;; +100D9;LINEAR B IDEOGRAM B255;Lo;0;L;;;;;N;;;;; +100DA;LINEAR B IDEOGRAM B256;Lo;0;L;;;;;N;;;;; +100DB;LINEAR B IDEOGRAM B257;Lo;0;L;;;;;N;;;;; +100DC;LINEAR B IDEOGRAM B258;Lo;0;L;;;;;N;;;;; +100DD;LINEAR B IDEOGRAM B259;Lo;0;L;;;;;N;;;;; +100DE;LINEAR B IDEOGRAM VESSEL B155;Lo;0;L;;;;;N;;;;; +100DF;LINEAR B IDEOGRAM VESSEL B200;Lo;0;L;;;;;N;;;;; +100E0;LINEAR B IDEOGRAM VESSEL B201;Lo;0;L;;;;;N;;;;; +100E1;LINEAR B IDEOGRAM VESSEL B202;Lo;0;L;;;;;N;;;;; +100E2;LINEAR B IDEOGRAM VESSEL B203;Lo;0;L;;;;;N;;;;; +100E3;LINEAR B IDEOGRAM VESSEL B204;Lo;0;L;;;;;N;;;;; +100E4;LINEAR B IDEOGRAM VESSEL B205;Lo;0;L;;;;;N;;;;; +100E5;LINEAR B IDEOGRAM VESSEL B206;Lo;0;L;;;;;N;;;;; +100E6;LINEAR B IDEOGRAM VESSEL B207;Lo;0;L;;;;;N;;;;; +100E7;LINEAR B IDEOGRAM VESSEL B208;Lo;0;L;;;;;N;;;;; +100E8;LINEAR B IDEOGRAM VESSEL B209;Lo;0;L;;;;;N;;;;; +100E9;LINEAR B IDEOGRAM VESSEL B210;Lo;0;L;;;;;N;;;;; +100EA;LINEAR B IDEOGRAM VESSEL B211;Lo;0;L;;;;;N;;;;; +100EB;LINEAR B IDEOGRAM VESSEL B212;Lo;0;L;;;;;N;;;;; +100EC;LINEAR B IDEOGRAM VESSEL B213;Lo;0;L;;;;;N;;;;; +100ED;LINEAR B IDEOGRAM VESSEL B214;Lo;0;L;;;;;N;;;;; +100EE;LINEAR B IDEOGRAM VESSEL B215;Lo;0;L;;;;;N;;;;; +100EF;LINEAR B IDEOGRAM VESSEL B216;Lo;0;L;;;;;N;;;;; +100F0;LINEAR B IDEOGRAM VESSEL B217;Lo;0;L;;;;;N;;;;; +100F1;LINEAR B IDEOGRAM VESSEL B218;Lo;0;L;;;;;N;;;;; +100F2;LINEAR B IDEOGRAM VESSEL B219;Lo;0;L;;;;;N;;;;; +100F3;LINEAR B IDEOGRAM VESSEL B221;Lo;0;L;;;;;N;;;;; +100F4;LINEAR B IDEOGRAM VESSEL B222;Lo;0;L;;;;;N;;;;; +100F5;LINEAR B IDEOGRAM VESSEL B226;Lo;0;L;;;;;N;;;;; +100F6;LINEAR B IDEOGRAM VESSEL B227;Lo;0;L;;;;;N;;;;; +100F7;LINEAR B IDEOGRAM VESSEL B228;Lo;0;L;;;;;N;;;;; +100F8;LINEAR B IDEOGRAM VESSEL B229;Lo;0;L;;;;;N;;;;; +100F9;LINEAR B IDEOGRAM VESSEL B250;Lo;0;L;;;;;N;;;;; +100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;; +10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;; +10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;; +10102;AEGEAN CHECK MARK;So;0;L;;;;;N;;;;; +10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;; +10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;; +10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;; +1010A;AEGEAN NUMBER FOUR;No;0;L;;;;4;N;;;;; +1010B;AEGEAN NUMBER FIVE;No;0;L;;;;5;N;;;;; +1010C;AEGEAN NUMBER SIX;No;0;L;;;;6;N;;;;; +1010D;AEGEAN NUMBER SEVEN;No;0;L;;;;7;N;;;;; +1010E;AEGEAN NUMBER EIGHT;No;0;L;;;;8;N;;;;; +1010F;AEGEAN NUMBER NINE;No;0;L;;;;9;N;;;;; +10110;AEGEAN NUMBER TEN;No;0;L;;;;10;N;;;;; +10111;AEGEAN NUMBER TWENTY;No;0;L;;;;20;N;;;;; +10112;AEGEAN NUMBER THIRTY;No;0;L;;;;30;N;;;;; +10113;AEGEAN NUMBER FORTY;No;0;L;;;;40;N;;;;; +10114;AEGEAN NUMBER FIFTY;No;0;L;;;;50;N;;;;; +10115;AEGEAN NUMBER SIXTY;No;0;L;;;;60;N;;;;; +10116;AEGEAN NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +10117;AEGEAN NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +10118;AEGEAN NUMBER NINETY;No;0;L;;;;90;N;;;;; +10119;AEGEAN NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +1011A;AEGEAN NUMBER TWO HUNDRED;No;0;L;;;;200;N;;;;; +1011B;AEGEAN NUMBER THREE HUNDRED;No;0;L;;;;300;N;;;;; +1011C;AEGEAN NUMBER FOUR HUNDRED;No;0;L;;;;400;N;;;;; +1011D;AEGEAN NUMBER FIVE HUNDRED;No;0;L;;;;500;N;;;;; +1011E;AEGEAN NUMBER SIX HUNDRED;No;0;L;;;;600;N;;;;; +1011F;AEGEAN NUMBER SEVEN HUNDRED;No;0;L;;;;700;N;;;;; +10120;AEGEAN NUMBER EIGHT HUNDRED;No;0;L;;;;800;N;;;;; +10121;AEGEAN NUMBER NINE HUNDRED;No;0;L;;;;900;N;;;;; +10122;AEGEAN NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +10123;AEGEAN NUMBER TWO THOUSAND;No;0;L;;;;2000;N;;;;; +10124;AEGEAN NUMBER THREE THOUSAND;No;0;L;;;;3000;N;;;;; +10125;AEGEAN NUMBER FOUR THOUSAND;No;0;L;;;;4000;N;;;;; +10126;AEGEAN NUMBER FIVE THOUSAND;No;0;L;;;;5000;N;;;;; +10127;AEGEAN NUMBER SIX THOUSAND;No;0;L;;;;6000;N;;;;; +10128;AEGEAN NUMBER SEVEN THOUSAND;No;0;L;;;;7000;N;;;;; +10129;AEGEAN NUMBER EIGHT THOUSAND;No;0;L;;;;8000;N;;;;; +1012A;AEGEAN NUMBER NINE THOUSAND;No;0;L;;;;9000;N;;;;; +1012B;AEGEAN NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; +1012C;AEGEAN NUMBER TWENTY THOUSAND;No;0;L;;;;20000;N;;;;; +1012D;AEGEAN NUMBER THIRTY THOUSAND;No;0;L;;;;30000;N;;;;; +1012E;AEGEAN NUMBER FORTY THOUSAND;No;0;L;;;;40000;N;;;;; +1012F;AEGEAN NUMBER FIFTY THOUSAND;No;0;L;;;;50000;N;;;;; +10130;AEGEAN NUMBER SIXTY THOUSAND;No;0;L;;;;60000;N;;;;; +10131;AEGEAN NUMBER SEVENTY THOUSAND;No;0;L;;;;70000;N;;;;; +10132;AEGEAN NUMBER EIGHTY THOUSAND;No;0;L;;;;80000;N;;;;; +10133;AEGEAN NUMBER NINETY THOUSAND;No;0;L;;;;90000;N;;;;; +10137;AEGEAN WEIGHT BASE UNIT;So;0;L;;;;;N;;;;; +10138;AEGEAN WEIGHT FIRST SUBUNIT;So;0;L;;;;;N;;;;; +10139;AEGEAN WEIGHT SECOND SUBUNIT;So;0;L;;;;;N;;;;; +1013A;AEGEAN WEIGHT THIRD SUBUNIT;So;0;L;;;;;N;;;;; +1013B;AEGEAN WEIGHT FOURTH SUBUNIT;So;0;L;;;;;N;;;;; +1013C;AEGEAN DRY MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;; +1013D;AEGEAN LIQUID MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;; +1013E;AEGEAN MEASURE SECOND SUBUNIT;So;0;L;;;;;N;;;;; +1013F;AEGEAN MEASURE THIRD SUBUNIT;So;0;L;;;;;N;;;;; +10140;GREEK ACROPHONIC ATTIC ONE QUARTER;Nl;0;ON;;;;1/4;N;;;;; +10141;GREEK ACROPHONIC ATTIC ONE HALF;Nl;0;ON;;;;1/2;N;;;;; +10142;GREEK ACROPHONIC ATTIC ONE DRACHMA;Nl;0;ON;;;;1;N;;;;; +10143;GREEK ACROPHONIC ATTIC FIVE;Nl;0;ON;;;;5;N;;;;; +10144;GREEK ACROPHONIC ATTIC FIFTY;Nl;0;ON;;;;50;N;;;;; +10145;GREEK ACROPHONIC ATTIC FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10146;GREEK ACROPHONIC ATTIC FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;; +10147;GREEK ACROPHONIC ATTIC FIFTY THOUSAND;Nl;0;ON;;;;50000;N;;;;; +10148;GREEK ACROPHONIC ATTIC FIVE TALENTS;Nl;0;ON;;;;5;N;;;;; +10149;GREEK ACROPHONIC ATTIC TEN TALENTS;Nl;0;ON;;;;10;N;;;;; +1014A;GREEK ACROPHONIC ATTIC FIFTY TALENTS;Nl;0;ON;;;;50;N;;;;; +1014B;GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS;Nl;0;ON;;;;100;N;;;;; +1014C;GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS;Nl;0;ON;;;;500;N;;;;; +1014D;GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS;Nl;0;ON;;;;1000;N;;;;; +1014E;GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS;Nl;0;ON;;;;5000;N;;;;; +1014F;GREEK ACROPHONIC ATTIC FIVE STATERS;Nl;0;ON;;;;5;N;;;;; +10150;GREEK ACROPHONIC ATTIC TEN STATERS;Nl;0;ON;;;;10;N;;;;; +10151;GREEK ACROPHONIC ATTIC FIFTY STATERS;Nl;0;ON;;;;50;N;;;;; +10152;GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS;Nl;0;ON;;;;100;N;;;;; +10153;GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS;Nl;0;ON;;;;500;N;;;;; +10154;GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS;Nl;0;ON;;;;1000;N;;;;; +10155;GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS;Nl;0;ON;;;;10000;N;;;;; +10156;GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS;Nl;0;ON;;;;50000;N;;;;; +10157;GREEK ACROPHONIC ATTIC TEN MNAS;Nl;0;ON;;;;10;N;;;;; +10158;GREEK ACROPHONIC HERAEUM ONE PLETHRON;Nl;0;ON;;;;1;N;;;;; +10159;GREEK ACROPHONIC THESPIAN ONE;Nl;0;ON;;;;1;N;;;;; +1015A;GREEK ACROPHONIC HERMIONIAN ONE;Nl;0;ON;;;;1;N;;;;; +1015B;GREEK ACROPHONIC EPIDAUREAN TWO;Nl;0;ON;;;;2;N;;;;; +1015C;GREEK ACROPHONIC THESPIAN TWO;Nl;0;ON;;;;2;N;;;;; +1015D;GREEK ACROPHONIC CYRENAIC TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;; +1015E;GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;; +1015F;GREEK ACROPHONIC TROEZENIAN FIVE;Nl;0;ON;;;;5;N;;;;; +10160;GREEK ACROPHONIC TROEZENIAN TEN;Nl;0;ON;;;;10;N;;;;; +10161;GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM;Nl;0;ON;;;;10;N;;;;; +10162;GREEK ACROPHONIC HERMIONIAN TEN;Nl;0;ON;;;;10;N;;;;; +10163;GREEK ACROPHONIC MESSENIAN TEN;Nl;0;ON;;;;10;N;;;;; +10164;GREEK ACROPHONIC THESPIAN TEN;Nl;0;ON;;;;10;N;;;;; +10165;GREEK ACROPHONIC THESPIAN THIRTY;Nl;0;ON;;;;30;N;;;;; +10166;GREEK ACROPHONIC TROEZENIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +10167;GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM;Nl;0;ON;;;;50;N;;;;; +10168;GREEK ACROPHONIC HERMIONIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +10169;GREEK ACROPHONIC THESPIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +1016A;GREEK ACROPHONIC THESPIAN ONE HUNDRED;Nl;0;ON;;;;100;N;;;;; +1016B;GREEK ACROPHONIC THESPIAN THREE HUNDRED;Nl;0;ON;;;;300;N;;;;; +1016C;GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016D;GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016E;GREEK ACROPHONIC THESPIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016F;GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10170;GREEK ACROPHONIC NAXIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10171;GREEK ACROPHONIC THESPIAN ONE THOUSAND;Nl;0;ON;;;;1000;N;;;;; +10172;GREEK ACROPHONIC THESPIAN FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;; +10173;GREEK ACROPHONIC DELPHIC FIVE MNAS;Nl;0;ON;;;;5;N;;;;; +10174;GREEK ACROPHONIC STRATIAN FIFTY MNAS;Nl;0;ON;;;;50;N;;;;; +10175;GREEK ONE HALF SIGN;No;0;ON;;;;1/2;N;;;;; +10176;GREEK ONE HALF SIGN ALTERNATE FORM;No;0;ON;;;;1/2;N;;;;; +10177;GREEK TWO THIRDS SIGN;No;0;ON;;;;2/3;N;;;;; +10178;GREEK THREE QUARTERS SIGN;No;0;ON;;;;3/4;N;;;;; +10179;GREEK YEAR SIGN;So;0;ON;;;;;N;;;;; +1017A;GREEK TALENT SIGN;So;0;ON;;;;;N;;;;; +1017B;GREEK DRACHMA SIGN;So;0;ON;;;;;N;;;;; +1017C;GREEK OBOL SIGN;So;0;ON;;;;;N;;;;; +1017D;GREEK TWO OBOLS SIGN;So;0;ON;;;;;N;;;;; +1017E;GREEK THREE OBOLS SIGN;So;0;ON;;;;;N;;;;; +1017F;GREEK FOUR OBOLS SIGN;So;0;ON;;;;;N;;;;; +10180;GREEK FIVE OBOLS SIGN;So;0;ON;;;;;N;;;;; +10181;GREEK METRETES SIGN;So;0;ON;;;;;N;;;;; +10182;GREEK KYATHOS BASE SIGN;So;0;ON;;;;;N;;;;; +10183;GREEK LITRA SIGN;So;0;ON;;;;;N;;;;; +10184;GREEK OUNKIA SIGN;So;0;ON;;;;;N;;;;; +10185;GREEK XESTES SIGN;So;0;ON;;;;;N;;;;; +10186;GREEK ARTABE SIGN;So;0;ON;;;;;N;;;;; +10187;GREEK AROURA SIGN;So;0;ON;;;;;N;;;;; +10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;; +10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;; +1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;; +10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;; +10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;; +10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;; +10193;ROMAN SEXTULA SIGN;So;0;ON;;;;;N;;;;; +10194;ROMAN DIMIDIA SEXTULA SIGN;So;0;ON;;;;;N;;;;; +10195;ROMAN SILIQUA SIGN;So;0;ON;;;;;N;;;;; +10196;ROMAN DENARIUS SIGN;So;0;ON;;;;;N;;;;; +10197;ROMAN QUINARIUS SIGN;So;0;ON;;;;;N;;;;; +10198;ROMAN SESTERTIUS SIGN;So;0;ON;;;;;N;;;;; +10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;; +1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;; +1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;; +101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;; +101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;; +101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;; +101D3;PHAISTOS DISC SIGN CAPTIVE;So;0;L;;;;;N;;;;; +101D4;PHAISTOS DISC SIGN CHILD;So;0;L;;;;;N;;;;; +101D5;PHAISTOS DISC SIGN WOMAN;So;0;L;;;;;N;;;;; +101D6;PHAISTOS DISC SIGN HELMET;So;0;L;;;;;N;;;;; +101D7;PHAISTOS DISC SIGN GAUNTLET;So;0;L;;;;;N;;;;; +101D8;PHAISTOS DISC SIGN TIARA;So;0;L;;;;;N;;;;; +101D9;PHAISTOS DISC SIGN ARROW;So;0;L;;;;;N;;;;; +101DA;PHAISTOS DISC SIGN BOW;So;0;L;;;;;N;;;;; +101DB;PHAISTOS DISC SIGN SHIELD;So;0;L;;;;;N;;;;; +101DC;PHAISTOS DISC SIGN CLUB;So;0;L;;;;;N;;;;; +101DD;PHAISTOS DISC SIGN MANACLES;So;0;L;;;;;N;;;;; +101DE;PHAISTOS DISC SIGN MATTOCK;So;0;L;;;;;N;;;;; +101DF;PHAISTOS DISC SIGN SAW;So;0;L;;;;;N;;;;; +101E0;PHAISTOS DISC SIGN LID;So;0;L;;;;;N;;;;; +101E1;PHAISTOS DISC SIGN BOOMERANG;So;0;L;;;;;N;;;;; +101E2;PHAISTOS DISC SIGN CARPENTRY PLANE;So;0;L;;;;;N;;;;; +101E3;PHAISTOS DISC SIGN DOLIUM;So;0;L;;;;;N;;;;; +101E4;PHAISTOS DISC SIGN COMB;So;0;L;;;;;N;;;;; +101E5;PHAISTOS DISC SIGN SLING;So;0;L;;;;;N;;;;; +101E6;PHAISTOS DISC SIGN COLUMN;So;0;L;;;;;N;;;;; +101E7;PHAISTOS DISC SIGN BEEHIVE;So;0;L;;;;;N;;;;; +101E8;PHAISTOS DISC SIGN SHIP;So;0;L;;;;;N;;;;; +101E9;PHAISTOS DISC SIGN HORN;So;0;L;;;;;N;;;;; +101EA;PHAISTOS DISC SIGN HIDE;So;0;L;;;;;N;;;;; +101EB;PHAISTOS DISC SIGN BULLS LEG;So;0;L;;;;;N;;;;; +101EC;PHAISTOS DISC SIGN CAT;So;0;L;;;;;N;;;;; +101ED;PHAISTOS DISC SIGN RAM;So;0;L;;;;;N;;;;; +101EE;PHAISTOS DISC SIGN EAGLE;So;0;L;;;;;N;;;;; +101EF;PHAISTOS DISC SIGN DOVE;So;0;L;;;;;N;;;;; +101F0;PHAISTOS DISC SIGN TUNNY;So;0;L;;;;;N;;;;; +101F1;PHAISTOS DISC SIGN BEE;So;0;L;;;;;N;;;;; +101F2;PHAISTOS DISC SIGN PLANE TREE;So;0;L;;;;;N;;;;; +101F3;PHAISTOS DISC SIGN VINE;So;0;L;;;;;N;;;;; +101F4;PHAISTOS DISC SIGN PAPYRUS;So;0;L;;;;;N;;;;; +101F5;PHAISTOS DISC SIGN ROSETTE;So;0;L;;;;;N;;;;; +101F6;PHAISTOS DISC SIGN LILY;So;0;L;;;;;N;;;;; +101F7;PHAISTOS DISC SIGN OX BACK;So;0;L;;;;;N;;;;; +101F8;PHAISTOS DISC SIGN FLUTE;So;0;L;;;;;N;;;;; +101F9;PHAISTOS DISC SIGN GRATER;So;0;L;;;;;N;;;;; +101FA;PHAISTOS DISC SIGN STRAINER;So;0;L;;;;;N;;;;; +101FB;PHAISTOS DISC SIGN SMALL AXE;So;0;L;;;;;N;;;;; +101FC;PHAISTOS DISC SIGN WAVY BAND;So;0;L;;;;;N;;;;; +101FD;PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE;Mn;220;NSM;;;;;N;;;;; +10280;LYCIAN LETTER A;Lo;0;L;;;;;N;;;;; +10281;LYCIAN LETTER E;Lo;0;L;;;;;N;;;;; +10282;LYCIAN LETTER B;Lo;0;L;;;;;N;;;;; +10283;LYCIAN LETTER BH;Lo;0;L;;;;;N;;;;; +10284;LYCIAN LETTER G;Lo;0;L;;;;;N;;;;; +10285;LYCIAN LETTER D;Lo;0;L;;;;;N;;;;; +10286;LYCIAN LETTER I;Lo;0;L;;;;;N;;;;; +10287;LYCIAN LETTER W;Lo;0;L;;;;;N;;;;; +10288;LYCIAN LETTER Z;Lo;0;L;;;;;N;;;;; +10289;LYCIAN LETTER TH;Lo;0;L;;;;;N;;;;; +1028A;LYCIAN LETTER J;Lo;0;L;;;;;N;;;;; +1028B;LYCIAN LETTER K;Lo;0;L;;;;;N;;;;; +1028C;LYCIAN LETTER Q;Lo;0;L;;;;;N;;;;; +1028D;LYCIAN LETTER L;Lo;0;L;;;;;N;;;;; +1028E;LYCIAN LETTER M;Lo;0;L;;;;;N;;;;; +1028F;LYCIAN LETTER N;Lo;0;L;;;;;N;;;;; +10290;LYCIAN LETTER MM;Lo;0;L;;;;;N;;;;; +10291;LYCIAN LETTER NN;Lo;0;L;;;;;N;;;;; +10292;LYCIAN LETTER U;Lo;0;L;;;;;N;;;;; +10293;LYCIAN LETTER P;Lo;0;L;;;;;N;;;;; +10294;LYCIAN LETTER KK;Lo;0;L;;;;;N;;;;; +10295;LYCIAN LETTER R;Lo;0;L;;;;;N;;;;; +10296;LYCIAN LETTER S;Lo;0;L;;;;;N;;;;; +10297;LYCIAN LETTER T;Lo;0;L;;;;;N;;;;; +10298;LYCIAN LETTER TT;Lo;0;L;;;;;N;;;;; +10299;LYCIAN LETTER AN;Lo;0;L;;;;;N;;;;; +1029A;LYCIAN LETTER EN;Lo;0;L;;;;;N;;;;; +1029B;LYCIAN LETTER H;Lo;0;L;;;;;N;;;;; +1029C;LYCIAN LETTER X;Lo;0;L;;;;;N;;;;; +102A0;CARIAN LETTER A;Lo;0;L;;;;;N;;;;; +102A1;CARIAN LETTER P2;Lo;0;L;;;;;N;;;;; +102A2;CARIAN LETTER D;Lo;0;L;;;;;N;;;;; +102A3;CARIAN LETTER L;Lo;0;L;;;;;N;;;;; +102A4;CARIAN LETTER UUU;Lo;0;L;;;;;N;;;;; +102A5;CARIAN LETTER R;Lo;0;L;;;;;N;;;;; +102A6;CARIAN LETTER LD;Lo;0;L;;;;;N;;;;; +102A7;CARIAN LETTER A2;Lo;0;L;;;;;N;;;;; +102A8;CARIAN LETTER Q;Lo;0;L;;;;;N;;;;; +102A9;CARIAN LETTER B;Lo;0;L;;;;;N;;;;; +102AA;CARIAN LETTER M;Lo;0;L;;;;;N;;;;; +102AB;CARIAN LETTER O;Lo;0;L;;;;;N;;;;; +102AC;CARIAN LETTER D2;Lo;0;L;;;;;N;;;;; +102AD;CARIAN LETTER T;Lo;0;L;;;;;N;;;;; +102AE;CARIAN LETTER SH;Lo;0;L;;;;;N;;;;; +102AF;CARIAN LETTER SH2;Lo;0;L;;;;;N;;;;; +102B0;CARIAN LETTER S;Lo;0;L;;;;;N;;;;; +102B1;CARIAN LETTER C-18;Lo;0;L;;;;;N;;;;; +102B2;CARIAN LETTER U;Lo;0;L;;;;;N;;;;; +102B3;CARIAN LETTER NN;Lo;0;L;;;;;N;;;;; +102B4;CARIAN LETTER X;Lo;0;L;;;;;N;;;;; +102B5;CARIAN LETTER N;Lo;0;L;;;;;N;;;;; +102B6;CARIAN LETTER TT2;Lo;0;L;;;;;N;;;;; +102B7;CARIAN LETTER P;Lo;0;L;;;;;N;;;;; +102B8;CARIAN LETTER SS;Lo;0;L;;;;;N;;;;; +102B9;CARIAN LETTER I;Lo;0;L;;;;;N;;;;; +102BA;CARIAN LETTER E;Lo;0;L;;;;;N;;;;; +102BB;CARIAN LETTER UUUU;Lo;0;L;;;;;N;;;;; +102BC;CARIAN LETTER K;Lo;0;L;;;;;N;;;;; +102BD;CARIAN LETTER K2;Lo;0;L;;;;;N;;;;; +102BE;CARIAN LETTER ND;Lo;0;L;;;;;N;;;;; +102BF;CARIAN LETTER UU;Lo;0;L;;;;;N;;;;; +102C0;CARIAN LETTER G;Lo;0;L;;;;;N;;;;; +102C1;CARIAN LETTER G2;Lo;0;L;;;;;N;;;;; +102C2;CARIAN LETTER ST;Lo;0;L;;;;;N;;;;; +102C3;CARIAN LETTER ST2;Lo;0;L;;;;;N;;;;; +102C4;CARIAN LETTER NG;Lo;0;L;;;;;N;;;;; +102C5;CARIAN LETTER II;Lo;0;L;;;;;N;;;;; +102C6;CARIAN LETTER C-39;Lo;0;L;;;;;N;;;;; +102C7;CARIAN LETTER TT;Lo;0;L;;;;;N;;;;; +102C8;CARIAN LETTER UUU2;Lo;0;L;;;;;N;;;;; +102C9;CARIAN LETTER RR;Lo;0;L;;;;;N;;;;; +102CA;CARIAN LETTER MB;Lo;0;L;;;;;N;;;;; +102CB;CARIAN LETTER MB2;Lo;0;L;;;;;N;;;;; +102CC;CARIAN LETTER MB3;Lo;0;L;;;;;N;;;;; +102CD;CARIAN LETTER MB4;Lo;0;L;;;;;N;;;;; +102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;; +102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;; +102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;; +10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;; +10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;; +10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;; +10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;; +10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;; +10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;; +10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;; +10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;; +10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;; +10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;; +1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;; +1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;; +1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;; +1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;; +1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;; +1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;Faliscan;;; +10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;; +10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;; +10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;; +10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;; +10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;; +10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;; +10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;; +10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;Faliscan;;; +10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;; +10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;; +1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;; +1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;Umbrian;;; +1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;Umbrian;;; +1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;Oscan;;; +1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;Oscan;;; +10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;; +10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;; +10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;; +10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;; +10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;; +10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;; +10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;; +10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;; +10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;; +10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;; +10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;; +10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;; +10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;; +10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;; +1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;; +1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;; +1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;; +1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;; +1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;; +1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;; +10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;; +10341;GOTHIC LETTER NINETY;Nl;0;L;;;;90;N;;;;; +10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;; +10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;; +10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;; +10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;; +10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;; +10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;; +10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;; +10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;; +1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;; +10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;; +10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;; +10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;; +10383;UGARITIC LETTER KHA;Lo;0;L;;;;;N;;;;; +10384;UGARITIC LETTER DELTA;Lo;0;L;;;;;N;;;;; +10385;UGARITIC LETTER HO;Lo;0;L;;;;;N;;;;; +10386;UGARITIC LETTER WO;Lo;0;L;;;;;N;;;;; +10387;UGARITIC LETTER ZETA;Lo;0;L;;;;;N;;;;; +10388;UGARITIC LETTER HOTA;Lo;0;L;;;;;N;;;;; +10389;UGARITIC LETTER TET;Lo;0;L;;;;;N;;;;; +1038A;UGARITIC LETTER YOD;Lo;0;L;;;;;N;;;;; +1038B;UGARITIC LETTER KAF;Lo;0;L;;;;;N;;;;; +1038C;UGARITIC LETTER SHIN;Lo;0;L;;;;;N;;;;; +1038D;UGARITIC LETTER LAMDA;Lo;0;L;;;;;N;;;;; +1038E;UGARITIC LETTER MEM;Lo;0;L;;;;;N;;;;; +1038F;UGARITIC LETTER DHAL;Lo;0;L;;;;;N;;;;; +10390;UGARITIC LETTER NUN;Lo;0;L;;;;;N;;;;; +10391;UGARITIC LETTER ZU;Lo;0;L;;;;;N;;;;; +10392;UGARITIC LETTER SAMKA;Lo;0;L;;;;;N;;;;; +10393;UGARITIC LETTER AIN;Lo;0;L;;;;;N;;;;; +10394;UGARITIC LETTER PU;Lo;0;L;;;;;N;;;;; +10395;UGARITIC LETTER SADE;Lo;0;L;;;;;N;;;;; +10396;UGARITIC LETTER QOPA;Lo;0;L;;;;;N;;;;; +10397;UGARITIC LETTER RASHA;Lo;0;L;;;;;N;;;;; +10398;UGARITIC LETTER THANNA;Lo;0;L;;;;;N;;;;; +10399;UGARITIC LETTER GHAIN;Lo;0;L;;;;;N;;;;; +1039A;UGARITIC LETTER TO;Lo;0;L;;;;;N;;;;; +1039B;UGARITIC LETTER I;Lo;0;L;;;;;N;;;;; +1039C;UGARITIC LETTER U;Lo;0;L;;;;;N;;;;; +1039D;UGARITIC LETTER SSU;Lo;0;L;;;;;N;;;;; +1039F;UGARITIC WORD DIVIDER;Po;0;L;;;;;N;;;;; +103A0;OLD PERSIAN SIGN A;Lo;0;L;;;;;N;;;;; +103A1;OLD PERSIAN SIGN I;Lo;0;L;;;;;N;;;;; +103A2;OLD PERSIAN SIGN U;Lo;0;L;;;;;N;;;;; +103A3;OLD PERSIAN SIGN KA;Lo;0;L;;;;;N;;;;; +103A4;OLD PERSIAN SIGN KU;Lo;0;L;;;;;N;;;;; +103A5;OLD PERSIAN SIGN GA;Lo;0;L;;;;;N;;;;; +103A6;OLD PERSIAN SIGN GU;Lo;0;L;;;;;N;;;;; +103A7;OLD PERSIAN SIGN XA;Lo;0;L;;;;;N;;;;; +103A8;OLD PERSIAN SIGN CA;Lo;0;L;;;;;N;;;;; +103A9;OLD PERSIAN SIGN JA;Lo;0;L;;;;;N;;;;; +103AA;OLD PERSIAN SIGN JI;Lo;0;L;;;;;N;;;;; +103AB;OLD PERSIAN SIGN TA;Lo;0;L;;;;;N;;;;; +103AC;OLD PERSIAN SIGN TU;Lo;0;L;;;;;N;;;;; +103AD;OLD PERSIAN SIGN DA;Lo;0;L;;;;;N;;;;; +103AE;OLD PERSIAN SIGN DI;Lo;0;L;;;;;N;;;;; +103AF;OLD PERSIAN SIGN DU;Lo;0;L;;;;;N;;;;; +103B0;OLD PERSIAN SIGN THA;Lo;0;L;;;;;N;;;;; +103B1;OLD PERSIAN SIGN PA;Lo;0;L;;;;;N;;;;; +103B2;OLD PERSIAN SIGN BA;Lo;0;L;;;;;N;;;;; +103B3;OLD PERSIAN SIGN FA;Lo;0;L;;;;;N;;;;; +103B4;OLD PERSIAN SIGN NA;Lo;0;L;;;;;N;;;;; +103B5;OLD PERSIAN SIGN NU;Lo;0;L;;;;;N;;;;; +103B6;OLD PERSIAN SIGN MA;Lo;0;L;;;;;N;;;;; +103B7;OLD PERSIAN SIGN MI;Lo;0;L;;;;;N;;;;; +103B8;OLD PERSIAN SIGN MU;Lo;0;L;;;;;N;;;;; +103B9;OLD PERSIAN SIGN YA;Lo;0;L;;;;;N;;;;; +103BA;OLD PERSIAN SIGN VA;Lo;0;L;;;;;N;;;;; +103BB;OLD PERSIAN SIGN VI;Lo;0;L;;;;;N;;;;; +103BC;OLD PERSIAN SIGN RA;Lo;0;L;;;;;N;;;;; +103BD;OLD PERSIAN SIGN RU;Lo;0;L;;;;;N;;;;; +103BE;OLD PERSIAN SIGN LA;Lo;0;L;;;;;N;;;;; +103BF;OLD PERSIAN SIGN SA;Lo;0;L;;;;;N;;;;; +103C0;OLD PERSIAN SIGN ZA;Lo;0;L;;;;;N;;;;; +103C1;OLD PERSIAN SIGN SHA;Lo;0;L;;;;;N;;;;; +103C2;OLD PERSIAN SIGN SSA;Lo;0;L;;;;;N;;;;; +103C3;OLD PERSIAN SIGN HA;Lo;0;L;;;;;N;;;;; +103C8;OLD PERSIAN SIGN AURAMAZDAA;Lo;0;L;;;;;N;;;;; +103C9;OLD PERSIAN SIGN AURAMAZDAA-2;Lo;0;L;;;;;N;;;;; +103CA;OLD PERSIAN SIGN AURAMAZDAAHA;Lo;0;L;;;;;N;;;;; +103CB;OLD PERSIAN SIGN XSHAAYATHIYA;Lo;0;L;;;;;N;;;;; +103CC;OLD PERSIAN SIGN DAHYAAUSH;Lo;0;L;;;;;N;;;;; +103CD;OLD PERSIAN SIGN DAHYAAUSH-2;Lo;0;L;;;;;N;;;;; +103CE;OLD PERSIAN SIGN BAGA;Lo;0;L;;;;;N;;;;; +103CF;OLD PERSIAN SIGN BUUMISH;Lo;0;L;;;;;N;;;;; +103D0;OLD PERSIAN WORD DIVIDER;Po;0;L;;;;;N;;;;; +103D1;OLD PERSIAN NUMBER ONE;Nl;0;L;;;;1;N;;;;; +103D2;OLD PERSIAN NUMBER TWO;Nl;0;L;;;;2;N;;;;; +103D3;OLD PERSIAN NUMBER TEN;Nl;0;L;;;;10;N;;;;; +103D4;OLD PERSIAN NUMBER TWENTY;Nl;0;L;;;;20;N;;;;; +103D5;OLD PERSIAN NUMBER HUNDRED;Nl;0;L;;;;100;N;;;;; +10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428; +10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429; +10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A; +10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B; +10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C; +10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D; +10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E; +10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F; +10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430; +10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431; +1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432; +1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433; +1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434; +1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435; +1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436; +1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437; +10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438; +10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439; +10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A; +10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B; +10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C; +10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D; +10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E; +10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F; +10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440; +10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441; +1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442; +1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443; +1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444; +1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445; +1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446; +1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447; +10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448; +10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449; +10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A; +10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B; +10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C; +10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D; +10426;DESERET CAPITAL LETTER OI;Lu;0;L;;;;;N;;;;1044E; +10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F; +10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400 +10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401 +1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402 +1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403 +1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404 +1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405 +1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406 +1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407 +10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408 +10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409 +10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A +10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B +10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C +10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D +10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E +10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F +10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410 +10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411 +1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412 +1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413 +1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414 +1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415 +1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416 +1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417 +10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418 +10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419 +10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A +10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B +10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C +10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D +10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E +10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F +10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420 +10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421 +1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422 +1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423 +1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424 +1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425 +1044E;DESERET SMALL LETTER OI;Ll;0;L;;;;;N;;;10426;;10426 +1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427 +10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;; +10451;SHAVIAN LETTER TOT;Lo;0;L;;;;;N;;;;; +10452;SHAVIAN LETTER KICK;Lo;0;L;;;;;N;;;;; +10453;SHAVIAN LETTER FEE;Lo;0;L;;;;;N;;;;; +10454;SHAVIAN LETTER THIGH;Lo;0;L;;;;;N;;;;; +10455;SHAVIAN LETTER SO;Lo;0;L;;;;;N;;;;; +10456;SHAVIAN LETTER SURE;Lo;0;L;;;;;N;;;;; +10457;SHAVIAN LETTER CHURCH;Lo;0;L;;;;;N;;;;; +10458;SHAVIAN LETTER YEA;Lo;0;L;;;;;N;;;;; +10459;SHAVIAN LETTER HUNG;Lo;0;L;;;;;N;;;;; +1045A;SHAVIAN LETTER BIB;Lo;0;L;;;;;N;;;;; +1045B;SHAVIAN LETTER DEAD;Lo;0;L;;;;;N;;;;; +1045C;SHAVIAN LETTER GAG;Lo;0;L;;;;;N;;;;; +1045D;SHAVIAN LETTER VOW;Lo;0;L;;;;;N;;;;; +1045E;SHAVIAN LETTER THEY;Lo;0;L;;;;;N;;;;; +1045F;SHAVIAN LETTER ZOO;Lo;0;L;;;;;N;;;;; +10460;SHAVIAN LETTER MEASURE;Lo;0;L;;;;;N;;;;; +10461;SHAVIAN LETTER JUDGE;Lo;0;L;;;;;N;;;;; +10462;SHAVIAN LETTER WOE;Lo;0;L;;;;;N;;;;; +10463;SHAVIAN LETTER HA-HA;Lo;0;L;;;;;N;;;;; +10464;SHAVIAN LETTER LOLL;Lo;0;L;;;;;N;;;;; +10465;SHAVIAN LETTER MIME;Lo;0;L;;;;;N;;;;; +10466;SHAVIAN LETTER IF;Lo;0;L;;;;;N;;;;; +10467;SHAVIAN LETTER EGG;Lo;0;L;;;;;N;;;;; +10468;SHAVIAN LETTER ASH;Lo;0;L;;;;;N;;;;; +10469;SHAVIAN LETTER ADO;Lo;0;L;;;;;N;;;;; +1046A;SHAVIAN LETTER ON;Lo;0;L;;;;;N;;;;; +1046B;SHAVIAN LETTER WOOL;Lo;0;L;;;;;N;;;;; +1046C;SHAVIAN LETTER OUT;Lo;0;L;;;;;N;;;;; +1046D;SHAVIAN LETTER AH;Lo;0;L;;;;;N;;;;; +1046E;SHAVIAN LETTER ROAR;Lo;0;L;;;;;N;;;;; +1046F;SHAVIAN LETTER NUN;Lo;0;L;;;;;N;;;;; +10470;SHAVIAN LETTER EAT;Lo;0;L;;;;;N;;;;; +10471;SHAVIAN LETTER AGE;Lo;0;L;;;;;N;;;;; +10472;SHAVIAN LETTER ICE;Lo;0;L;;;;;N;;;;; +10473;SHAVIAN LETTER UP;Lo;0;L;;;;;N;;;;; +10474;SHAVIAN LETTER OAK;Lo;0;L;;;;;N;;;;; +10475;SHAVIAN LETTER OOZE;Lo;0;L;;;;;N;;;;; +10476;SHAVIAN LETTER OIL;Lo;0;L;;;;;N;;;;; +10477;SHAVIAN LETTER AWE;Lo;0;L;;;;;N;;;;; +10478;SHAVIAN LETTER ARE;Lo;0;L;;;;;N;;;;; +10479;SHAVIAN LETTER OR;Lo;0;L;;;;;N;;;;; +1047A;SHAVIAN LETTER AIR;Lo;0;L;;;;;N;;;;; +1047B;SHAVIAN LETTER ERR;Lo;0;L;;;;;N;;;;; +1047C;SHAVIAN LETTER ARRAY;Lo;0;L;;;;;N;;;;; +1047D;SHAVIAN LETTER EAR;Lo;0;L;;;;;N;;;;; +1047E;SHAVIAN LETTER IAN;Lo;0;L;;;;;N;;;;; +1047F;SHAVIAN LETTER YEW;Lo;0;L;;;;;N;;;;; +10480;OSMANYA LETTER ALEF;Lo;0;L;;;;;N;;;;; +10481;OSMANYA LETTER BA;Lo;0;L;;;;;N;;;;; +10482;OSMANYA LETTER TA;Lo;0;L;;;;;N;;;;; +10483;OSMANYA LETTER JA;Lo;0;L;;;;;N;;;;; +10484;OSMANYA LETTER XA;Lo;0;L;;;;;N;;;;; +10485;OSMANYA LETTER KHA;Lo;0;L;;;;;N;;;;; +10486;OSMANYA LETTER DEEL;Lo;0;L;;;;;N;;;;; +10487;OSMANYA LETTER RA;Lo;0;L;;;;;N;;;;; +10488;OSMANYA LETTER SA;Lo;0;L;;;;;N;;;;; +10489;OSMANYA LETTER SHIIN;Lo;0;L;;;;;N;;;;; +1048A;OSMANYA LETTER DHA;Lo;0;L;;;;;N;;;;; +1048B;OSMANYA LETTER CAYN;Lo;0;L;;;;;N;;;;; +1048C;OSMANYA LETTER GA;Lo;0;L;;;;;N;;;;; +1048D;OSMANYA LETTER FA;Lo;0;L;;;;;N;;;;; +1048E;OSMANYA LETTER QAAF;Lo;0;L;;;;;N;;;;; +1048F;OSMANYA LETTER KAAF;Lo;0;L;;;;;N;;;;; +10490;OSMANYA LETTER LAAN;Lo;0;L;;;;;N;;;;; +10491;OSMANYA LETTER MIIN;Lo;0;L;;;;;N;;;;; +10492;OSMANYA LETTER NUUN;Lo;0;L;;;;;N;;;;; +10493;OSMANYA LETTER WAW;Lo;0;L;;;;;N;;;;; +10494;OSMANYA LETTER HA;Lo;0;L;;;;;N;;;;; +10495;OSMANYA LETTER YA;Lo;0;L;;;;;N;;;;; +10496;OSMANYA LETTER A;Lo;0;L;;;;;N;;;;; +10497;OSMANYA LETTER E;Lo;0;L;;;;;N;;;;; +10498;OSMANYA LETTER I;Lo;0;L;;;;;N;;;;; +10499;OSMANYA LETTER O;Lo;0;L;;;;;N;;;;; +1049A;OSMANYA LETTER U;Lo;0;L;;;;;N;;;;; +1049B;OSMANYA LETTER AA;Lo;0;L;;;;;N;;;;; +1049C;OSMANYA LETTER EE;Lo;0;L;;;;;N;;;;; +1049D;OSMANYA LETTER OO;Lo;0;L;;;;;N;;;;; +104A0;OSMANYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +104A1;OSMANYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +104A2;OSMANYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +104A3;OSMANYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +104A4;OSMANYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +104A5;OSMANYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +104A6;OSMANYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;; +10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;; +10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;; +10803;CYPRIOT SYLLABLE O;Lo;0;R;;;;;N;;;;; +10804;CYPRIOT SYLLABLE U;Lo;0;R;;;;;N;;;;; +10805;CYPRIOT SYLLABLE JA;Lo;0;R;;;;;N;;;;; +10808;CYPRIOT SYLLABLE JO;Lo;0;R;;;;;N;;;;; +1080A;CYPRIOT SYLLABLE KA;Lo;0;R;;;;;N;;;;; +1080B;CYPRIOT SYLLABLE KE;Lo;0;R;;;;;N;;;;; +1080C;CYPRIOT SYLLABLE KI;Lo;0;R;;;;;N;;;;; +1080D;CYPRIOT SYLLABLE KO;Lo;0;R;;;;;N;;;;; +1080E;CYPRIOT SYLLABLE KU;Lo;0;R;;;;;N;;;;; +1080F;CYPRIOT SYLLABLE LA;Lo;0;R;;;;;N;;;;; +10810;CYPRIOT SYLLABLE LE;Lo;0;R;;;;;N;;;;; +10811;CYPRIOT SYLLABLE LI;Lo;0;R;;;;;N;;;;; +10812;CYPRIOT SYLLABLE LO;Lo;0;R;;;;;N;;;;; +10813;CYPRIOT SYLLABLE LU;Lo;0;R;;;;;N;;;;; +10814;CYPRIOT SYLLABLE MA;Lo;0;R;;;;;N;;;;; +10815;CYPRIOT SYLLABLE ME;Lo;0;R;;;;;N;;;;; +10816;CYPRIOT SYLLABLE MI;Lo;0;R;;;;;N;;;;; +10817;CYPRIOT SYLLABLE MO;Lo;0;R;;;;;N;;;;; +10818;CYPRIOT SYLLABLE MU;Lo;0;R;;;;;N;;;;; +10819;CYPRIOT SYLLABLE NA;Lo;0;R;;;;;N;;;;; +1081A;CYPRIOT SYLLABLE NE;Lo;0;R;;;;;N;;;;; +1081B;CYPRIOT SYLLABLE NI;Lo;0;R;;;;;N;;;;; +1081C;CYPRIOT SYLLABLE NO;Lo;0;R;;;;;N;;;;; +1081D;CYPRIOT SYLLABLE NU;Lo;0;R;;;;;N;;;;; +1081E;CYPRIOT SYLLABLE PA;Lo;0;R;;;;;N;;;;; +1081F;CYPRIOT SYLLABLE PE;Lo;0;R;;;;;N;;;;; +10820;CYPRIOT SYLLABLE PI;Lo;0;R;;;;;N;;;;; +10821;CYPRIOT SYLLABLE PO;Lo;0;R;;;;;N;;;;; +10822;CYPRIOT SYLLABLE PU;Lo;0;R;;;;;N;;;;; +10823;CYPRIOT SYLLABLE RA;Lo;0;R;;;;;N;;;;; +10824;CYPRIOT SYLLABLE RE;Lo;0;R;;;;;N;;;;; +10825;CYPRIOT SYLLABLE RI;Lo;0;R;;;;;N;;;;; +10826;CYPRIOT SYLLABLE RO;Lo;0;R;;;;;N;;;;; +10827;CYPRIOT SYLLABLE RU;Lo;0;R;;;;;N;;;;; +10828;CYPRIOT SYLLABLE SA;Lo;0;R;;;;;N;;;;; +10829;CYPRIOT SYLLABLE SE;Lo;0;R;;;;;N;;;;; +1082A;CYPRIOT SYLLABLE SI;Lo;0;R;;;;;N;;;;; +1082B;CYPRIOT SYLLABLE SO;Lo;0;R;;;;;N;;;;; +1082C;CYPRIOT SYLLABLE SU;Lo;0;R;;;;;N;;;;; +1082D;CYPRIOT SYLLABLE TA;Lo;0;R;;;;;N;;;;; +1082E;CYPRIOT SYLLABLE TE;Lo;0;R;;;;;N;;;;; +1082F;CYPRIOT SYLLABLE TI;Lo;0;R;;;;;N;;;;; +10830;CYPRIOT SYLLABLE TO;Lo;0;R;;;;;N;;;;; +10831;CYPRIOT SYLLABLE TU;Lo;0;R;;;;;N;;;;; +10832;CYPRIOT SYLLABLE WA;Lo;0;R;;;;;N;;;;; +10833;CYPRIOT SYLLABLE WE;Lo;0;R;;;;;N;;;;; +10834;CYPRIOT SYLLABLE WI;Lo;0;R;;;;;N;;;;; +10835;CYPRIOT SYLLABLE WO;Lo;0;R;;;;;N;;;;; +10837;CYPRIOT SYLLABLE XA;Lo;0;R;;;;;N;;;;; +10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;; +1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;; +1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;; +10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;; +10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;; +10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;; +10903;PHOENICIAN LETTER DELT;Lo;0;R;;;;;N;;;;; +10904;PHOENICIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10905;PHOENICIAN LETTER WAU;Lo;0;R;;;;;N;;;;; +10906;PHOENICIAN LETTER ZAI;Lo;0;R;;;;;N;;;;; +10907;PHOENICIAN LETTER HET;Lo;0;R;;;;;N;;;;; +10908;PHOENICIAN LETTER TET;Lo;0;R;;;;;N;;;;; +10909;PHOENICIAN LETTER YOD;Lo;0;R;;;;;N;;;;; +1090A;PHOENICIAN LETTER KAF;Lo;0;R;;;;;N;;;;; +1090B;PHOENICIAN LETTER LAMD;Lo;0;R;;;;;N;;;;; +1090C;PHOENICIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +1090D;PHOENICIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +1090E;PHOENICIAN LETTER SEMK;Lo;0;R;;;;;N;;;;; +1090F;PHOENICIAN LETTER AIN;Lo;0;R;;;;;N;;;;; +10910;PHOENICIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10911;PHOENICIAN LETTER SADE;Lo;0;R;;;;;N;;;;; +10912;PHOENICIAN LETTER QOF;Lo;0;R;;;;;N;;;;; +10913;PHOENICIAN LETTER ROSH;Lo;0;R;;;;;N;;;;; +10914;PHOENICIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10915;PHOENICIAN LETTER TAU;Lo;0;R;;;;;N;;;;; +10916;PHOENICIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;; +10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;; +10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;; +10922;LYDIAN LETTER G;Lo;0;R;;;;;N;;;;; +10923;LYDIAN LETTER D;Lo;0;R;;;;;N;;;;; +10924;LYDIAN LETTER E;Lo;0;R;;;;;N;;;;; +10925;LYDIAN LETTER V;Lo;0;R;;;;;N;;;;; +10926;LYDIAN LETTER I;Lo;0;R;;;;;N;;;;; +10927;LYDIAN LETTER Y;Lo;0;R;;;;;N;;;;; +10928;LYDIAN LETTER K;Lo;0;R;;;;;N;;;;; +10929;LYDIAN LETTER L;Lo;0;R;;;;;N;;;;; +1092A;LYDIAN LETTER M;Lo;0;R;;;;;N;;;;; +1092B;LYDIAN LETTER N;Lo;0;R;;;;;N;;;;; +1092C;LYDIAN LETTER O;Lo;0;R;;;;;N;;;;; +1092D;LYDIAN LETTER R;Lo;0;R;;;;;N;;;;; +1092E;LYDIAN LETTER SS;Lo;0;R;;;;;N;;;;; +1092F;LYDIAN LETTER T;Lo;0;R;;;;;N;;;;; +10930;LYDIAN LETTER U;Lo;0;R;;;;;N;;;;; +10931;LYDIAN LETTER F;Lo;0;R;;;;;N;;;;; +10932;LYDIAN LETTER Q;Lo;0;R;;;;;N;;;;; +10933;LYDIAN LETTER S;Lo;0;R;;;;;N;;;;; +10934;LYDIAN LETTER TT;Lo;0;R;;;;;N;;;;; +10935;LYDIAN LETTER AN;Lo;0;R;;;;;N;;;;; +10936;LYDIAN LETTER EN;Lo;0;R;;;;;N;;;;; +10937;LYDIAN LETTER LY;Lo;0;R;;;;;N;;;;; +10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;; +10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;; +1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;; +10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;; +10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +10A03;KHAROSHTHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +10A05;KHAROSHTHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +10A06;KHAROSHTHI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +10A0C;KHAROSHTHI VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +10A0D;KHAROSHTHI SIGN DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;; +10A0E;KHAROSHTHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +10A0F;KHAROSHTHI SIGN VISARGA;Mn;230;NSM;;;;;N;;;;; +10A10;KHAROSHTHI LETTER KA;Lo;0;R;;;;;N;;;;; +10A11;KHAROSHTHI LETTER KHA;Lo;0;R;;;;;N;;;;; +10A12;KHAROSHTHI LETTER GA;Lo;0;R;;;;;N;;;;; +10A13;KHAROSHTHI LETTER GHA;Lo;0;R;;;;;N;;;;; +10A15;KHAROSHTHI LETTER CA;Lo;0;R;;;;;N;;;;; +10A16;KHAROSHTHI LETTER CHA;Lo;0;R;;;;;N;;;;; +10A17;KHAROSHTHI LETTER JA;Lo;0;R;;;;;N;;;;; +10A19;KHAROSHTHI LETTER NYA;Lo;0;R;;;;;N;;;;; +10A1A;KHAROSHTHI LETTER TTA;Lo;0;R;;;;;N;;;;; +10A1B;KHAROSHTHI LETTER TTHA;Lo;0;R;;;;;N;;;;; +10A1C;KHAROSHTHI LETTER DDA;Lo;0;R;;;;;N;;;;; +10A1D;KHAROSHTHI LETTER DDHA;Lo;0;R;;;;;N;;;;; +10A1E;KHAROSHTHI LETTER NNA;Lo;0;R;;;;;N;;;;; +10A1F;KHAROSHTHI LETTER TA;Lo;0;R;;;;;N;;;;; +10A20;KHAROSHTHI LETTER THA;Lo;0;R;;;;;N;;;;; +10A21;KHAROSHTHI LETTER DA;Lo;0;R;;;;;N;;;;; +10A22;KHAROSHTHI LETTER DHA;Lo;0;R;;;;;N;;;;; +10A23;KHAROSHTHI LETTER NA;Lo;0;R;;;;;N;;;;; +10A24;KHAROSHTHI LETTER PA;Lo;0;R;;;;;N;;;;; +10A25;KHAROSHTHI LETTER PHA;Lo;0;R;;;;;N;;;;; +10A26;KHAROSHTHI LETTER BA;Lo;0;R;;;;;N;;;;; +10A27;KHAROSHTHI LETTER BHA;Lo;0;R;;;;;N;;;;; +10A28;KHAROSHTHI LETTER MA;Lo;0;R;;;;;N;;;;; +10A29;KHAROSHTHI LETTER YA;Lo;0;R;;;;;N;;;;; +10A2A;KHAROSHTHI LETTER RA;Lo;0;R;;;;;N;;;;; +10A2B;KHAROSHTHI LETTER LA;Lo;0;R;;;;;N;;;;; +10A2C;KHAROSHTHI LETTER VA;Lo;0;R;;;;;N;;;;; +10A2D;KHAROSHTHI LETTER SHA;Lo;0;R;;;;;N;;;;; +10A2E;KHAROSHTHI LETTER SSA;Lo;0;R;;;;;N;;;;; +10A2F;KHAROSHTHI LETTER SA;Lo;0;R;;;;;N;;;;; +10A30;KHAROSHTHI LETTER ZA;Lo;0;R;;;;;N;;;;; +10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;; +10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;; +10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;; +10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;; +10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;; +10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;; +10A3F;KHAROSHTHI VIRAMA;Mn;9;NSM;;;;;N;;;;; +10A40;KHAROSHTHI DIGIT ONE;No;0;R;;;1;1;N;;;;; +10A41;KHAROSHTHI DIGIT TWO;No;0;R;;;2;2;N;;;;; +10A42;KHAROSHTHI DIGIT THREE;No;0;R;;;3;3;N;;;;; +10A43;KHAROSHTHI DIGIT FOUR;No;0;R;;;4;4;N;;;;; +10A44;KHAROSHTHI NUMBER TEN;No;0;R;;;;10;N;;;;; +10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;; +10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;; +10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;; +10A53;KHAROSHTHI PUNCTUATION CRESCENT BAR;Po;0;R;;;;;N;;;;; +10A54;KHAROSHTHI PUNCTUATION MANGALAM;Po;0;R;;;;;N;;;;; +10A55;KHAROSHTHI PUNCTUATION LOTUS;Po;0;R;;;;;N;;;;; +10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;; +10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;; +10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;; +12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;; +12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;; +12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;; +12003;CUNEIFORM SIGN A TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12004;CUNEIFORM SIGN A TIMES HA;Lo;0;L;;;;;N;;;;; +12005;CUNEIFORM SIGN A TIMES IGI;Lo;0;L;;;;;N;;;;; +12006;CUNEIFORM SIGN A TIMES LAGAR GUNU;Lo;0;L;;;;;N;;;;; +12007;CUNEIFORM SIGN A TIMES MUSH;Lo;0;L;;;;;N;;;;; +12008;CUNEIFORM SIGN A TIMES SAG;Lo;0;L;;;;;N;;;;; +12009;CUNEIFORM SIGN A2;Lo;0;L;;;;;N;;;;; +1200A;CUNEIFORM SIGN AB;Lo;0;L;;;;;N;;;;; +1200B;CUNEIFORM SIGN AB TIMES ASH2;Lo;0;L;;;;;N;;;;; +1200C;CUNEIFORM SIGN AB TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;; +1200D;CUNEIFORM SIGN AB TIMES GAL;Lo;0;L;;;;;N;;;;; +1200E;CUNEIFORM SIGN AB TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1200F;CUNEIFORM SIGN AB TIMES HA;Lo;0;L;;;;;N;;;;; +12010;CUNEIFORM SIGN AB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12011;CUNEIFORM SIGN AB TIMES IMIN;Lo;0;L;;;;;N;;;;; +12012;CUNEIFORM SIGN AB TIMES LAGAB;Lo;0;L;;;;;N;;;;; +12013;CUNEIFORM SIGN AB TIMES SHESH;Lo;0;L;;;;;N;;;;; +12014;CUNEIFORM SIGN AB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +12015;CUNEIFORM SIGN AB GUNU;Lo;0;L;;;;;N;;;;; +12016;CUNEIFORM SIGN AB2;Lo;0;L;;;;;N;;;;; +12017;CUNEIFORM SIGN AB2 TIMES BALAG;Lo;0;L;;;;;N;;;;; +12018;CUNEIFORM SIGN AB2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12019;CUNEIFORM SIGN AB2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +1201A;CUNEIFORM SIGN AB2 TIMES SHA3;Lo;0;L;;;;;N;;;;; +1201B;CUNEIFORM SIGN AB2 TIMES TAK4;Lo;0;L;;;;;N;;;;; +1201C;CUNEIFORM SIGN AD;Lo;0;L;;;;;N;;;;; +1201D;CUNEIFORM SIGN AK;Lo;0;L;;;;;N;;;;; +1201E;CUNEIFORM SIGN AK TIMES ERIN2;Lo;0;L;;;;;N;;;;; +1201F;CUNEIFORM SIGN AK TIMES SHITA PLUS GISH;Lo;0;L;;;;;N;;;;; +12020;CUNEIFORM SIGN AL;Lo;0;L;;;;;N;;;;; +12021;CUNEIFORM SIGN AL TIMES AL;Lo;0;L;;;;;N;;;;; +12022;CUNEIFORM SIGN AL TIMES DIM2;Lo;0;L;;;;;N;;;;; +12023;CUNEIFORM SIGN AL TIMES GISH;Lo;0;L;;;;;N;;;;; +12024;CUNEIFORM SIGN AL TIMES HA;Lo;0;L;;;;;N;;;;; +12025;CUNEIFORM SIGN AL TIMES KAD3;Lo;0;L;;;;;N;;;;; +12026;CUNEIFORM SIGN AL TIMES KI;Lo;0;L;;;;;N;;;;; +12027;CUNEIFORM SIGN AL TIMES SHE;Lo;0;L;;;;;N;;;;; +12028;CUNEIFORM SIGN AL TIMES USH;Lo;0;L;;;;;N;;;;; +12029;CUNEIFORM SIGN ALAN;Lo;0;L;;;;;N;;;;; +1202A;CUNEIFORM SIGN ALEPH;Lo;0;L;;;;;N;;;;; +1202B;CUNEIFORM SIGN AMAR;Lo;0;L;;;;;N;;;;; +1202C;CUNEIFORM SIGN AMAR TIMES SHE;Lo;0;L;;;;;N;;;;; +1202D;CUNEIFORM SIGN AN;Lo;0;L;;;;;N;;;;; +1202E;CUNEIFORM SIGN AN OVER AN;Lo;0;L;;;;;N;;;;; +1202F;CUNEIFORM SIGN AN THREE TIMES;Lo;0;L;;;;;N;;;;; +12030;CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA;Lo;0;L;;;;;N;;;;; +12031;CUNEIFORM SIGN AN PLUS NAGA SQUARED;Lo;0;L;;;;;N;;;;; +12032;CUNEIFORM SIGN ANSHE;Lo;0;L;;;;;N;;;;; +12033;CUNEIFORM SIGN APIN;Lo;0;L;;;;;N;;;;; +12034;CUNEIFORM SIGN ARAD;Lo;0;L;;;;;N;;;;; +12035;CUNEIFORM SIGN ARAD TIMES KUR;Lo;0;L;;;;;N;;;;; +12036;CUNEIFORM SIGN ARKAB;Lo;0;L;;;;;N;;;;; +12037;CUNEIFORM SIGN ASAL2;Lo;0;L;;;;;N;;;;; +12038;CUNEIFORM SIGN ASH;Lo;0;L;;;;;N;;;;; +12039;CUNEIFORM SIGN ASH ZIDA TENU;Lo;0;L;;;;;N;;;;; +1203A;CUNEIFORM SIGN ASH KABA TENU;Lo;0;L;;;;;N;;;;; +1203B;CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP;Lo;0;L;;;;;N;;;;; +1203C;CUNEIFORM SIGN ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;; +1203D;CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;; +1203E;CUNEIFORM SIGN ASH2;Lo;0;L;;;;;N;;;;; +1203F;CUNEIFORM SIGN ASHGAB;Lo;0;L;;;;;N;;;;; +12040;CUNEIFORM SIGN BA;Lo;0;L;;;;;N;;;;; +12041;CUNEIFORM SIGN BAD;Lo;0;L;;;;;N;;;;; +12042;CUNEIFORM SIGN BAG3;Lo;0;L;;;;;N;;;;; +12043;CUNEIFORM SIGN BAHAR2;Lo;0;L;;;;;N;;;;; +12044;CUNEIFORM SIGN BAL;Lo;0;L;;;;;N;;;;; +12045;CUNEIFORM SIGN BAL OVER BAL;Lo;0;L;;;;;N;;;;; +12046;CUNEIFORM SIGN BALAG;Lo;0;L;;;;;N;;;;; +12047;CUNEIFORM SIGN BAR;Lo;0;L;;;;;N;;;;; +12048;CUNEIFORM SIGN BARA2;Lo;0;L;;;;;N;;;;; +12049;CUNEIFORM SIGN BI;Lo;0;L;;;;;N;;;;; +1204A;CUNEIFORM SIGN BI TIMES A;Lo;0;L;;;;;N;;;;; +1204B;CUNEIFORM SIGN BI TIMES GAR;Lo;0;L;;;;;N;;;;; +1204C;CUNEIFORM SIGN BI TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +1204D;CUNEIFORM SIGN BU;Lo;0;L;;;;;N;;;;; +1204E;CUNEIFORM SIGN BU OVER BU AB;Lo;0;L;;;;;N;;;;; +1204F;CUNEIFORM SIGN BU OVER BU UN;Lo;0;L;;;;;N;;;;; +12050;CUNEIFORM SIGN BU CROSSING BU;Lo;0;L;;;;;N;;;;; +12051;CUNEIFORM SIGN BULUG;Lo;0;L;;;;;N;;;;; +12052;CUNEIFORM SIGN BULUG OVER BULUG;Lo;0;L;;;;;N;;;;; +12053;CUNEIFORM SIGN BUR;Lo;0;L;;;;;N;;;;; +12054;CUNEIFORM SIGN BUR2;Lo;0;L;;;;;N;;;;; +12055;CUNEIFORM SIGN DA;Lo;0;L;;;;;N;;;;; +12056;CUNEIFORM SIGN DAG;Lo;0;L;;;;;N;;;;; +12057;CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH;Lo;0;L;;;;;N;;;;; +12058;CUNEIFORM SIGN DAG KISIM5 TIMES AMAR;Lo;0;L;;;;;N;;;;; +12059;CUNEIFORM SIGN DAG KISIM5 TIMES BALAG;Lo;0;L;;;;;N;;;;; +1205A;CUNEIFORM SIGN DAG KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;; +1205B;CUNEIFORM SIGN DAG KISIM5 TIMES GA;Lo;0;L;;;;;N;;;;; +1205C;CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH;Lo;0;L;;;;;N;;;;; +1205D;CUNEIFORM SIGN DAG KISIM5 TIMES GI;Lo;0;L;;;;;N;;;;; +1205E;CUNEIFORM SIGN DAG KISIM5 TIMES GIR2;Lo;0;L;;;;;N;;;;; +1205F;CUNEIFORM SIGN DAG KISIM5 TIMES GUD;Lo;0;L;;;;;N;;;;; +12060;CUNEIFORM SIGN DAG KISIM5 TIMES HA;Lo;0;L;;;;;N;;;;; +12061;CUNEIFORM SIGN DAG KISIM5 TIMES IR;Lo;0;L;;;;;N;;;;; +12062;CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU;Lo;0;L;;;;;N;;;;; +12063;CUNEIFORM SIGN DAG KISIM5 TIMES KAK;Lo;0;L;;;;;N;;;;; +12064;CUNEIFORM SIGN DAG KISIM5 TIMES LA;Lo;0;L;;;;;N;;;;; +12065;CUNEIFORM SIGN DAG KISIM5 TIMES LU;Lo;0;L;;;;;N;;;;; +12066;CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2;Lo;0;L;;;;;N;;;;; +12067;CUNEIFORM SIGN DAG KISIM5 TIMES LUM;Lo;0;L;;;;;N;;;;; +12068;CUNEIFORM SIGN DAG KISIM5 TIMES NE;Lo;0;L;;;;;N;;;;; +12069;CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;; +1206A;CUNEIFORM SIGN DAG KISIM5 TIMES SI;Lo;0;L;;;;;N;;;;; +1206B;CUNEIFORM SIGN DAG KISIM5 TIMES TAK4;Lo;0;L;;;;;N;;;;; +1206C;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2;Lo;0;L;;;;;N;;;;; +1206D;CUNEIFORM SIGN DAG KISIM5 TIMES USH;Lo;0;L;;;;;N;;;;; +1206E;CUNEIFORM SIGN DAM;Lo;0;L;;;;;N;;;;; +1206F;CUNEIFORM SIGN DAR;Lo;0;L;;;;;N;;;;; +12070;CUNEIFORM SIGN DARA3;Lo;0;L;;;;;N;;;;; +12071;CUNEIFORM SIGN DARA4;Lo;0;L;;;;;N;;;;; +12072;CUNEIFORM SIGN DI;Lo;0;L;;;;;N;;;;; +12073;CUNEIFORM SIGN DIB;Lo;0;L;;;;;N;;;;; +12074;CUNEIFORM SIGN DIM;Lo;0;L;;;;;N;;;;; +12075;CUNEIFORM SIGN DIM TIMES SHE;Lo;0;L;;;;;N;;;;; +12076;CUNEIFORM SIGN DIM2;Lo;0;L;;;;;N;;;;; +12077;CUNEIFORM SIGN DIN;Lo;0;L;;;;;N;;;;; +12078;CUNEIFORM SIGN DIN KASKAL U GUNU DISH;Lo;0;L;;;;;N;;;;; +12079;CUNEIFORM SIGN DISH;Lo;0;L;;;;;N;;;;; +1207A;CUNEIFORM SIGN DU;Lo;0;L;;;;;N;;;;; +1207B;CUNEIFORM SIGN DU OVER DU;Lo;0;L;;;;;N;;;;; +1207C;CUNEIFORM SIGN DU GUNU;Lo;0;L;;;;;N;;;;; +1207D;CUNEIFORM SIGN DU SHESHIG;Lo;0;L;;;;;N;;;;; +1207E;CUNEIFORM SIGN DUB;Lo;0;L;;;;;N;;;;; +1207F;CUNEIFORM SIGN DUB TIMES ESH2;Lo;0;L;;;;;N;;;;; +12080;CUNEIFORM SIGN DUB2;Lo;0;L;;;;;N;;;;; +12081;CUNEIFORM SIGN DUG;Lo;0;L;;;;;N;;;;; +12082;CUNEIFORM SIGN DUGUD;Lo;0;L;;;;;N;;;;; +12083;CUNEIFORM SIGN DUH;Lo;0;L;;;;;N;;;;; +12084;CUNEIFORM SIGN DUN;Lo;0;L;;;;;N;;;;; +12085;CUNEIFORM SIGN DUN3;Lo;0;L;;;;;N;;;;; +12086;CUNEIFORM SIGN DUN3 GUNU;Lo;0;L;;;;;N;;;;; +12087;CUNEIFORM SIGN DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;; +12088;CUNEIFORM SIGN DUN4;Lo;0;L;;;;;N;;;;; +12089;CUNEIFORM SIGN DUR2;Lo;0;L;;;;;N;;;;; +1208A;CUNEIFORM SIGN E;Lo;0;L;;;;;N;;;;; +1208B;CUNEIFORM SIGN E TIMES PAP;Lo;0;L;;;;;N;;;;; +1208C;CUNEIFORM SIGN E OVER E NUN OVER NUN;Lo;0;L;;;;;N;;;;; +1208D;CUNEIFORM SIGN E2;Lo;0;L;;;;;N;;;;; +1208E;CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA;Lo;0;L;;;;;N;;;;; +1208F;CUNEIFORM SIGN E2 TIMES GAR;Lo;0;L;;;;;N;;;;; +12090;CUNEIFORM SIGN E2 TIMES MI;Lo;0;L;;;;;N;;;;; +12091;CUNEIFORM SIGN E2 TIMES SAL;Lo;0;L;;;;;N;;;;; +12092;CUNEIFORM SIGN E2 TIMES SHE;Lo;0;L;;;;;N;;;;; +12093;CUNEIFORM SIGN E2 TIMES U;Lo;0;L;;;;;N;;;;; +12094;CUNEIFORM SIGN EDIN;Lo;0;L;;;;;N;;;;; +12095;CUNEIFORM SIGN EGIR;Lo;0;L;;;;;N;;;;; +12096;CUNEIFORM SIGN EL;Lo;0;L;;;;;N;;;;; +12097;CUNEIFORM SIGN EN;Lo;0;L;;;;;N;;;;; +12098;CUNEIFORM SIGN EN TIMES GAN2;Lo;0;L;;;;;N;;;;; +12099;CUNEIFORM SIGN EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1209A;CUNEIFORM SIGN EN TIMES ME;Lo;0;L;;;;;N;;;;; +1209B;CUNEIFORM SIGN EN CROSSING EN;Lo;0;L;;;;;N;;;;; +1209C;CUNEIFORM SIGN EN OPPOSING EN;Lo;0;L;;;;;N;;;;; +1209D;CUNEIFORM SIGN EN SQUARED;Lo;0;L;;;;;N;;;;; +1209E;CUNEIFORM SIGN EREN;Lo;0;L;;;;;N;;;;; +1209F;CUNEIFORM SIGN ERIN2;Lo;0;L;;;;;N;;;;; +120A0;CUNEIFORM SIGN ESH2;Lo;0;L;;;;;N;;;;; +120A1;CUNEIFORM SIGN EZEN;Lo;0;L;;;;;N;;;;; +120A2;CUNEIFORM SIGN EZEN TIMES A;Lo;0;L;;;;;N;;;;; +120A3;CUNEIFORM SIGN EZEN TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;; +120A4;CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +120A5;CUNEIFORM SIGN EZEN TIMES AN;Lo;0;L;;;;;N;;;;; +120A6;CUNEIFORM SIGN EZEN TIMES BAD;Lo;0;L;;;;;N;;;;; +120A7;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;; +120A8;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;; +120A9;CUNEIFORM SIGN EZEN TIMES HA;Lo;0;L;;;;;N;;;;; +120AA;CUNEIFORM SIGN EZEN TIMES HA GUNU;Lo;0;L;;;;;N;;;;; +120AB;CUNEIFORM SIGN EZEN TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +120AC;CUNEIFORM SIGN EZEN TIMES KASKAL;Lo;0;L;;;;;N;;;;; +120AD;CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED;Lo;0;L;;;;;N;;;;; +120AE;CUNEIFORM SIGN EZEN TIMES KU3;Lo;0;L;;;;;N;;;;; +120AF;CUNEIFORM SIGN EZEN TIMES LA;Lo;0;L;;;;;N;;;;; +120B0;CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +120B1;CUNEIFORM SIGN EZEN TIMES LI;Lo;0;L;;;;;N;;;;; +120B2;CUNEIFORM SIGN EZEN TIMES LU;Lo;0;L;;;;;N;;;;; +120B3;CUNEIFORM SIGN EZEN TIMES U2;Lo;0;L;;;;;N;;;;; +120B4;CUNEIFORM SIGN EZEN TIMES UD;Lo;0;L;;;;;N;;;;; +120B5;CUNEIFORM SIGN GA;Lo;0;L;;;;;N;;;;; +120B6;CUNEIFORM SIGN GA GUNU;Lo;0;L;;;;;N;;;;; +120B7;CUNEIFORM SIGN GA2;Lo;0;L;;;;;N;;;;; +120B8;CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;; +120B9;CUNEIFORM SIGN GA2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;; +120BA;CUNEIFORM SIGN GA2 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;; +120BB;CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB;Lo;0;L;;;;;N;;;;; +120BC;CUNEIFORM SIGN GA2 TIMES AN;Lo;0;L;;;;;N;;;;; +120BD;CUNEIFORM SIGN GA2 TIMES ASH;Lo;0;L;;;;;N;;;;; +120BE;CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL;Lo;0;L;;;;;N;;;;; +120BF;CUNEIFORM SIGN GA2 TIMES BAD;Lo;0;L;;;;;N;;;;; +120C0;CUNEIFORM SIGN GA2 TIMES BAR PLUS RA;Lo;0;L;;;;;N;;;;; +120C1;CUNEIFORM SIGN GA2 TIMES BUR;Lo;0;L;;;;;N;;;;; +120C2;CUNEIFORM SIGN GA2 TIMES BUR PLUS RA;Lo;0;L;;;;;N;;;;; +120C3;CUNEIFORM SIGN GA2 TIMES DA;Lo;0;L;;;;;N;;;;; +120C4;CUNEIFORM SIGN GA2 TIMES DI;Lo;0;L;;;;;N;;;;; +120C5;CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE;Lo;0;L;;;;;N;;;;; +120C6;CUNEIFORM SIGN GA2 TIMES DUB;Lo;0;L;;;;;N;;;;; +120C7;CUNEIFORM SIGN GA2 TIMES EL;Lo;0;L;;;;;N;;;;; +120C8;CUNEIFORM SIGN GA2 TIMES EL PLUS LA;Lo;0;L;;;;;N;;;;; +120C9;CUNEIFORM SIGN GA2 TIMES EN;Lo;0;L;;;;;N;;;;; +120CA;CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +120CB;CUNEIFORM SIGN GA2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +120CC;CUNEIFORM SIGN GA2 TIMES GAR;Lo;0;L;;;;;N;;;;; +120CD;CUNEIFORM SIGN GA2 TIMES GI;Lo;0;L;;;;;N;;;;; +120CE;CUNEIFORM SIGN GA2 TIMES GI4;Lo;0;L;;;;;N;;;;; +120CF;CUNEIFORM SIGN GA2 TIMES GI4 PLUS A;Lo;0;L;;;;;N;;;;; +120D0;CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU;Lo;0;L;;;;;N;;;;; +120D1;CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2;Lo;0;L;;;;;N;;;;; +120D2;CUNEIFORM SIGN GA2 TIMES HAL;Lo;0;L;;;;;N;;;;; +120D3;CUNEIFORM SIGN GA2 TIMES HAL PLUS LA;Lo;0;L;;;;;N;;;;; +120D4;CUNEIFORM SIGN GA2 TIMES HI PLUS LI;Lo;0;L;;;;;N;;;;; +120D5;CUNEIFORM SIGN GA2 TIMES HUB2;Lo;0;L;;;;;N;;;;; +120D6;CUNEIFORM SIGN GA2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +120D7;CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH;Lo;0;L;;;;;N;;;;; +120D8;CUNEIFORM SIGN GA2 TIMES KAK;Lo;0;L;;;;;N;;;;; +120D9;CUNEIFORM SIGN GA2 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +120DA;CUNEIFORM SIGN GA2 TIMES KID;Lo;0;L;;;;;N;;;;; +120DB;CUNEIFORM SIGN GA2 TIMES KID PLUS LAL;Lo;0;L;;;;;N;;;;; +120DC;CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN;Lo;0;L;;;;;N;;;;; +120DD;CUNEIFORM SIGN GA2 TIMES LA;Lo;0;L;;;;;N;;;;; +120DE;CUNEIFORM SIGN GA2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +120DF;CUNEIFORM SIGN GA2 TIMES MI;Lo;0;L;;;;;N;;;;; +120E0;CUNEIFORM SIGN GA2 TIMES NUN;Lo;0;L;;;;;N;;;;; +120E1;CUNEIFORM SIGN GA2 TIMES NUN OVER NUN;Lo;0;L;;;;;N;;;;; +120E2;CUNEIFORM SIGN GA2 TIMES PA;Lo;0;L;;;;;N;;;;; +120E3;CUNEIFORM SIGN GA2 TIMES SAL;Lo;0;L;;;;;N;;;;; +120E4;CUNEIFORM SIGN GA2 TIMES SAR;Lo;0;L;;;;;N;;;;; +120E5;CUNEIFORM SIGN GA2 TIMES SHE;Lo;0;L;;;;;N;;;;; +120E6;CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR;Lo;0;L;;;;;N;;;;; +120E7;CUNEIFORM SIGN GA2 TIMES SHID;Lo;0;L;;;;;N;;;;; +120E8;CUNEIFORM SIGN GA2 TIMES SUM;Lo;0;L;;;;;N;;;;; +120E9;CUNEIFORM SIGN GA2 TIMES TAK4;Lo;0;L;;;;;N;;;;; +120EA;CUNEIFORM SIGN GA2 TIMES U;Lo;0;L;;;;;N;;;;; +120EB;CUNEIFORM SIGN GA2 TIMES UD;Lo;0;L;;;;;N;;;;; +120EC;CUNEIFORM SIGN GA2 TIMES UD PLUS DU;Lo;0;L;;;;;N;;;;; +120ED;CUNEIFORM SIGN GA2 OVER GA2;Lo;0;L;;;;;N;;;;; +120EE;CUNEIFORM SIGN GABA;Lo;0;L;;;;;N;;;;; +120EF;CUNEIFORM SIGN GABA CROSSING GABA;Lo;0;L;;;;;N;;;;; +120F0;CUNEIFORM SIGN GAD;Lo;0;L;;;;;N;;;;; +120F1;CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +120F2;CUNEIFORM SIGN GAL;Lo;0;L;;;;;N;;;;; +120F3;CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +120F4;CUNEIFORM SIGN GALAM;Lo;0;L;;;;;N;;;;; +120F5;CUNEIFORM SIGN GAM;Lo;0;L;;;;;N;;;;; +120F6;CUNEIFORM SIGN GAN;Lo;0;L;;;;;N;;;;; +120F7;CUNEIFORM SIGN GAN2;Lo;0;L;;;;;N;;;;; +120F8;CUNEIFORM SIGN GAN2 TENU;Lo;0;L;;;;;N;;;;; +120F9;CUNEIFORM SIGN GAN2 OVER GAN2;Lo;0;L;;;;;N;;;;; +120FA;CUNEIFORM SIGN GAN2 CROSSING GAN2;Lo;0;L;;;;;N;;;;; +120FB;CUNEIFORM SIGN GAR;Lo;0;L;;;;;N;;;;; +120FC;CUNEIFORM SIGN GAR3;Lo;0;L;;;;;N;;;;; +120FD;CUNEIFORM SIGN GASHAN;Lo;0;L;;;;;N;;;;; +120FE;CUNEIFORM SIGN GESHTIN;Lo;0;L;;;;;N;;;;; +120FF;CUNEIFORM SIGN GESHTIN TIMES KUR;Lo;0;L;;;;;N;;;;; +12100;CUNEIFORM SIGN GI;Lo;0;L;;;;;N;;;;; +12101;CUNEIFORM SIGN GI TIMES E;Lo;0;L;;;;;N;;;;; +12102;CUNEIFORM SIGN GI TIMES U;Lo;0;L;;;;;N;;;;; +12103;CUNEIFORM SIGN GI CROSSING GI;Lo;0;L;;;;;N;;;;; +12104;CUNEIFORM SIGN GI4;Lo;0;L;;;;;N;;;;; +12105;CUNEIFORM SIGN GI4 OVER GI4;Lo;0;L;;;;;N;;;;; +12106;CUNEIFORM SIGN GI4 CROSSING GI4;Lo;0;L;;;;;N;;;;; +12107;CUNEIFORM SIGN GIDIM;Lo;0;L;;;;;N;;;;; +12108;CUNEIFORM SIGN GIR2;Lo;0;L;;;;;N;;;;; +12109;CUNEIFORM SIGN GIR2 GUNU;Lo;0;L;;;;;N;;;;; +1210A;CUNEIFORM SIGN GIR3;Lo;0;L;;;;;N;;;;; +1210B;CUNEIFORM SIGN GIR3 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;; +1210C;CUNEIFORM SIGN GIR3 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1210D;CUNEIFORM SIGN GIR3 TIMES IGI;Lo;0;L;;;;;N;;;;; +1210E;CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI;Lo;0;L;;;;;N;;;;; +1210F;CUNEIFORM SIGN GIR3 TIMES PA;Lo;0;L;;;;;N;;;;; +12110;CUNEIFORM SIGN GISAL;Lo;0;L;;;;;N;;;;; +12111;CUNEIFORM SIGN GISH;Lo;0;L;;;;;N;;;;; +12112;CUNEIFORM SIGN GISH CROSSING GISH;Lo;0;L;;;;;N;;;;; +12113;CUNEIFORM SIGN GISH TIMES BAD;Lo;0;L;;;;;N;;;;; +12114;CUNEIFORM SIGN GISH TIMES TAK4;Lo;0;L;;;;;N;;;;; +12115;CUNEIFORM SIGN GISH TENU;Lo;0;L;;;;;N;;;;; +12116;CUNEIFORM SIGN GU;Lo;0;L;;;;;N;;;;; +12117;CUNEIFORM SIGN GU CROSSING GU;Lo;0;L;;;;;N;;;;; +12118;CUNEIFORM SIGN GU2;Lo;0;L;;;;;N;;;;; +12119;CUNEIFORM SIGN GU2 TIMES KAK;Lo;0;L;;;;;N;;;;; +1211A;CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +1211B;CUNEIFORM SIGN GU2 TIMES NUN;Lo;0;L;;;;;N;;;;; +1211C;CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2;Lo;0;L;;;;;N;;;;; +1211D;CUNEIFORM SIGN GU2 GUNU;Lo;0;L;;;;;N;;;;; +1211E;CUNEIFORM SIGN GUD;Lo;0;L;;;;;N;;;;; +1211F;CUNEIFORM SIGN GUD TIMES A PLUS KUR;Lo;0;L;;;;;N;;;;; +12120;CUNEIFORM SIGN GUD TIMES KUR;Lo;0;L;;;;;N;;;;; +12121;CUNEIFORM SIGN GUD OVER GUD LUGAL;Lo;0;L;;;;;N;;;;; +12122;CUNEIFORM SIGN GUL;Lo;0;L;;;;;N;;;;; +12123;CUNEIFORM SIGN GUM;Lo;0;L;;;;;N;;;;; +12124;CUNEIFORM SIGN GUM TIMES SHE;Lo;0;L;;;;;N;;;;; +12125;CUNEIFORM SIGN GUR;Lo;0;L;;;;;N;;;;; +12126;CUNEIFORM SIGN GUR7;Lo;0;L;;;;;N;;;;; +12127;CUNEIFORM SIGN GURUN;Lo;0;L;;;;;N;;;;; +12128;CUNEIFORM SIGN GURUSH;Lo;0;L;;;;;N;;;;; +12129;CUNEIFORM SIGN HA;Lo;0;L;;;;;N;;;;; +1212A;CUNEIFORM SIGN HA TENU;Lo;0;L;;;;;N;;;;; +1212B;CUNEIFORM SIGN HA GUNU;Lo;0;L;;;;;N;;;;; +1212C;CUNEIFORM SIGN HAL;Lo;0;L;;;;;N;;;;; +1212D;CUNEIFORM SIGN HI;Lo;0;L;;;;;N;;;;; +1212E;CUNEIFORM SIGN HI TIMES ASH;Lo;0;L;;;;;N;;;;; +1212F;CUNEIFORM SIGN HI TIMES ASH2;Lo;0;L;;;;;N;;;;; +12130;CUNEIFORM SIGN HI TIMES BAD;Lo;0;L;;;;;N;;;;; +12131;CUNEIFORM SIGN HI TIMES DISH;Lo;0;L;;;;;N;;;;; +12132;CUNEIFORM SIGN HI TIMES GAD;Lo;0;L;;;;;N;;;;; +12133;CUNEIFORM SIGN HI TIMES KIN;Lo;0;L;;;;;N;;;;; +12134;CUNEIFORM SIGN HI TIMES NUN;Lo;0;L;;;;;N;;;;; +12135;CUNEIFORM SIGN HI TIMES SHE;Lo;0;L;;;;;N;;;;; +12136;CUNEIFORM SIGN HI TIMES U;Lo;0;L;;;;;N;;;;; +12137;CUNEIFORM SIGN HU;Lo;0;L;;;;;N;;;;; +12138;CUNEIFORM SIGN HUB2;Lo;0;L;;;;;N;;;;; +12139;CUNEIFORM SIGN HUB2 TIMES AN;Lo;0;L;;;;;N;;;;; +1213A;CUNEIFORM SIGN HUB2 TIMES HAL;Lo;0;L;;;;;N;;;;; +1213B;CUNEIFORM SIGN HUB2 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +1213C;CUNEIFORM SIGN HUB2 TIMES LISH;Lo;0;L;;;;;N;;;;; +1213D;CUNEIFORM SIGN HUB2 TIMES UD;Lo;0;L;;;;;N;;;;; +1213E;CUNEIFORM SIGN HUL2;Lo;0;L;;;;;N;;;;; +1213F;CUNEIFORM SIGN I;Lo;0;L;;;;;N;;;;; +12140;CUNEIFORM SIGN I A;Lo;0;L;;;;;N;;;;; +12141;CUNEIFORM SIGN IB;Lo;0;L;;;;;N;;;;; +12142;CUNEIFORM SIGN IDIM;Lo;0;L;;;;;N;;;;; +12143;CUNEIFORM SIGN IDIM OVER IDIM BUR;Lo;0;L;;;;;N;;;;; +12144;CUNEIFORM SIGN IDIM OVER IDIM SQUARED;Lo;0;L;;;;;N;;;;; +12145;CUNEIFORM SIGN IG;Lo;0;L;;;;;N;;;;; +12146;CUNEIFORM SIGN IGI;Lo;0;L;;;;;N;;;;; +12147;CUNEIFORM SIGN IGI DIB;Lo;0;L;;;;;N;;;;; +12148;CUNEIFORM SIGN IGI RI;Lo;0;L;;;;;N;;;;; +12149;CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD;Lo;0;L;;;;;N;;;;; +1214A;CUNEIFORM SIGN IGI GUNU;Lo;0;L;;;;;N;;;;; +1214B;CUNEIFORM SIGN IL;Lo;0;L;;;;;N;;;;; +1214C;CUNEIFORM SIGN IL TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1214D;CUNEIFORM SIGN IL2;Lo;0;L;;;;;N;;;;; +1214E;CUNEIFORM SIGN IM;Lo;0;L;;;;;N;;;;; +1214F;CUNEIFORM SIGN IM TIMES TAK4;Lo;0;L;;;;;N;;;;; +12150;CUNEIFORM SIGN IM CROSSING IM;Lo;0;L;;;;;N;;;;; +12151;CUNEIFORM SIGN IM OPPOSING IM;Lo;0;L;;;;;N;;;;; +12152;CUNEIFORM SIGN IM SQUARED;Lo;0;L;;;;;N;;;;; +12153;CUNEIFORM SIGN IMIN;Lo;0;L;;;;;N;;;;; +12154;CUNEIFORM SIGN IN;Lo;0;L;;;;;N;;;;; +12155;CUNEIFORM SIGN IR;Lo;0;L;;;;;N;;;;; +12156;CUNEIFORM SIGN ISH;Lo;0;L;;;;;N;;;;; +12157;CUNEIFORM SIGN KA;Lo;0;L;;;;;N;;;;; +12158;CUNEIFORM SIGN KA TIMES A;Lo;0;L;;;;;N;;;;; +12159;CUNEIFORM SIGN KA TIMES AD;Lo;0;L;;;;;N;;;;; +1215A;CUNEIFORM SIGN KA TIMES AD PLUS KU3;Lo;0;L;;;;;N;;;;; +1215B;CUNEIFORM SIGN KA TIMES ASH2;Lo;0;L;;;;;N;;;;; +1215C;CUNEIFORM SIGN KA TIMES BAD;Lo;0;L;;;;;N;;;;; +1215D;CUNEIFORM SIGN KA TIMES BALAG;Lo;0;L;;;;;N;;;;; +1215E;CUNEIFORM SIGN KA TIMES BAR;Lo;0;L;;;;;N;;;;; +1215F;CUNEIFORM SIGN KA TIMES BI;Lo;0;L;;;;;N;;;;; +12160;CUNEIFORM SIGN KA TIMES ERIN2;Lo;0;L;;;;;N;;;;; +12161;CUNEIFORM SIGN KA TIMES ESH2;Lo;0;L;;;;;N;;;;; +12162;CUNEIFORM SIGN KA TIMES GA;Lo;0;L;;;;;N;;;;; +12163;CUNEIFORM SIGN KA TIMES GAL;Lo;0;L;;;;;N;;;;; +12164;CUNEIFORM SIGN KA TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12165;CUNEIFORM SIGN KA TIMES GAR;Lo;0;L;;;;;N;;;;; +12166;CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A;Lo;0;L;;;;;N;;;;; +12167;CUNEIFORM SIGN KA TIMES GI;Lo;0;L;;;;;N;;;;; +12168;CUNEIFORM SIGN KA TIMES GIR2;Lo;0;L;;;;;N;;;;; +12169;CUNEIFORM SIGN KA TIMES GISH PLUS SAR;Lo;0;L;;;;;N;;;;; +1216A;CUNEIFORM SIGN KA TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;; +1216B;CUNEIFORM SIGN KA TIMES GU;Lo;0;L;;;;;N;;;;; +1216C;CUNEIFORM SIGN KA TIMES GUR7;Lo;0;L;;;;;N;;;;; +1216D;CUNEIFORM SIGN KA TIMES IGI;Lo;0;L;;;;;N;;;;; +1216E;CUNEIFORM SIGN KA TIMES IM;Lo;0;L;;;;;N;;;;; +1216F;CUNEIFORM SIGN KA TIMES KAK;Lo;0;L;;;;;N;;;;; +12170;CUNEIFORM SIGN KA TIMES KI;Lo;0;L;;;;;N;;;;; +12171;CUNEIFORM SIGN KA TIMES KID;Lo;0;L;;;;;N;;;;; +12172;CUNEIFORM SIGN KA TIMES LI;Lo;0;L;;;;;N;;;;; +12173;CUNEIFORM SIGN KA TIMES LU;Lo;0;L;;;;;N;;;;; +12174;CUNEIFORM SIGN KA TIMES ME;Lo;0;L;;;;;N;;;;; +12175;CUNEIFORM SIGN KA TIMES ME PLUS DU;Lo;0;L;;;;;N;;;;; +12176;CUNEIFORM SIGN KA TIMES ME PLUS GI;Lo;0;L;;;;;N;;;;; +12177;CUNEIFORM SIGN KA TIMES ME PLUS TE;Lo;0;L;;;;;N;;;;; +12178;CUNEIFORM SIGN KA TIMES MI;Lo;0;L;;;;;N;;;;; +12179;CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ;Lo;0;L;;;;;N;;;;; +1217A;CUNEIFORM SIGN KA TIMES NE;Lo;0;L;;;;;N;;;;; +1217B;CUNEIFORM SIGN KA TIMES NUN;Lo;0;L;;;;;N;;;;; +1217C;CUNEIFORM SIGN KA TIMES PI;Lo;0;L;;;;;N;;;;; +1217D;CUNEIFORM SIGN KA TIMES RU;Lo;0;L;;;;;N;;;;; +1217E;CUNEIFORM SIGN KA TIMES SA;Lo;0;L;;;;;N;;;;; +1217F;CUNEIFORM SIGN KA TIMES SAR;Lo;0;L;;;;;N;;;;; +12180;CUNEIFORM SIGN KA TIMES SHA;Lo;0;L;;;;;N;;;;; +12181;CUNEIFORM SIGN KA TIMES SHE;Lo;0;L;;;;;N;;;;; +12182;CUNEIFORM SIGN KA TIMES SHID;Lo;0;L;;;;;N;;;;; +12183;CUNEIFORM SIGN KA TIMES SHU;Lo;0;L;;;;;N;;;;; +12184;CUNEIFORM SIGN KA TIMES SIG;Lo;0;L;;;;;N;;;;; +12185;CUNEIFORM SIGN KA TIMES SUHUR;Lo;0;L;;;;;N;;;;; +12186;CUNEIFORM SIGN KA TIMES TAR;Lo;0;L;;;;;N;;;;; +12187;CUNEIFORM SIGN KA TIMES U;Lo;0;L;;;;;N;;;;; +12188;CUNEIFORM SIGN KA TIMES U2;Lo;0;L;;;;;N;;;;; +12189;CUNEIFORM SIGN KA TIMES UD;Lo;0;L;;;;;N;;;;; +1218A;CUNEIFORM SIGN KA TIMES UMUM TIMES PA;Lo;0;L;;;;;N;;;;; +1218B;CUNEIFORM SIGN KA TIMES USH;Lo;0;L;;;;;N;;;;; +1218C;CUNEIFORM SIGN KA TIMES ZI;Lo;0;L;;;;;N;;;;; +1218D;CUNEIFORM SIGN KA2;Lo;0;L;;;;;N;;;;; +1218E;CUNEIFORM SIGN KA2 CROSSING KA2;Lo;0;L;;;;;N;;;;; +1218F;CUNEIFORM SIGN KAB;Lo;0;L;;;;;N;;;;; +12190;CUNEIFORM SIGN KAD2;Lo;0;L;;;;;N;;;;; +12191;CUNEIFORM SIGN KAD3;Lo;0;L;;;;;N;;;;; +12192;CUNEIFORM SIGN KAD4;Lo;0;L;;;;;N;;;;; +12193;CUNEIFORM SIGN KAD5;Lo;0;L;;;;;N;;;;; +12194;CUNEIFORM SIGN KAD5 OVER KAD5;Lo;0;L;;;;;N;;;;; +12195;CUNEIFORM SIGN KAK;Lo;0;L;;;;;N;;;;; +12196;CUNEIFORM SIGN KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12197;CUNEIFORM SIGN KAL;Lo;0;L;;;;;N;;;;; +12198;CUNEIFORM SIGN KAL TIMES BAD;Lo;0;L;;;;;N;;;;; +12199;CUNEIFORM SIGN KAL CROSSING KAL;Lo;0;L;;;;;N;;;;; +1219A;CUNEIFORM SIGN KAM2;Lo;0;L;;;;;N;;;;; +1219B;CUNEIFORM SIGN KAM4;Lo;0;L;;;;;N;;;;; +1219C;CUNEIFORM SIGN KASKAL;Lo;0;L;;;;;N;;;;; +1219D;CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +1219E;CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +1219F;CUNEIFORM SIGN KESH2;Lo;0;L;;;;;N;;;;; +121A0;CUNEIFORM SIGN KI;Lo;0;L;;;;;N;;;;; +121A1;CUNEIFORM SIGN KI TIMES BAD;Lo;0;L;;;;;N;;;;; +121A2;CUNEIFORM SIGN KI TIMES U;Lo;0;L;;;;;N;;;;; +121A3;CUNEIFORM SIGN KI TIMES UD;Lo;0;L;;;;;N;;;;; +121A4;CUNEIFORM SIGN KID;Lo;0;L;;;;;N;;;;; +121A5;CUNEIFORM SIGN KIN;Lo;0;L;;;;;N;;;;; +121A6;CUNEIFORM SIGN KISAL;Lo;0;L;;;;;N;;;;; +121A7;CUNEIFORM SIGN KISH;Lo;0;L;;;;;N;;;;; +121A8;CUNEIFORM SIGN KISIM5;Lo;0;L;;;;;N;;;;; +121A9;CUNEIFORM SIGN KISIM5 OVER KISIM5;Lo;0;L;;;;;N;;;;; +121AA;CUNEIFORM SIGN KU;Lo;0;L;;;;;N;;;;; +121AB;CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2;Lo;0;L;;;;;N;;;;; +121AC;CUNEIFORM SIGN KU3;Lo;0;L;;;;;N;;;;; +121AD;CUNEIFORM SIGN KU4;Lo;0;L;;;;;N;;;;; +121AE;CUNEIFORM SIGN KU4 VARIANT FORM;Lo;0;L;;;;;N;;;;; +121AF;CUNEIFORM SIGN KU7;Lo;0;L;;;;;N;;;;; +121B0;CUNEIFORM SIGN KUL;Lo;0;L;;;;;N;;;;; +121B1;CUNEIFORM SIGN KUL GUNU;Lo;0;L;;;;;N;;;;; +121B2;CUNEIFORM SIGN KUN;Lo;0;L;;;;;N;;;;; +121B3;CUNEIFORM SIGN KUR;Lo;0;L;;;;;N;;;;; +121B4;CUNEIFORM SIGN KUR OPPOSING KUR;Lo;0;L;;;;;N;;;;; +121B5;CUNEIFORM SIGN KUSHU2;Lo;0;L;;;;;N;;;;; +121B6;CUNEIFORM SIGN KWU318;Lo;0;L;;;;;N;;;;; +121B7;CUNEIFORM SIGN LA;Lo;0;L;;;;;N;;;;; +121B8;CUNEIFORM SIGN LAGAB;Lo;0;L;;;;;N;;;;; +121B9;CUNEIFORM SIGN LAGAB TIMES A;Lo;0;L;;;;;N;;;;; +121BA;CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;; +121BB;CUNEIFORM SIGN LAGAB TIMES A PLUS GAR;Lo;0;L;;;;;N;;;;; +121BC;CUNEIFORM SIGN LAGAB TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;; +121BD;CUNEIFORM SIGN LAGAB TIMES AL;Lo;0;L;;;;;N;;;;; +121BE;CUNEIFORM SIGN LAGAB TIMES AN;Lo;0;L;;;;;N;;;;; +121BF;CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU;Lo;0;L;;;;;N;;;;; +121C0;CUNEIFORM SIGN LAGAB TIMES BAD;Lo;0;L;;;;;N;;;;; +121C1;CUNEIFORM SIGN LAGAB TIMES BI;Lo;0;L;;;;;N;;;;; +121C2;CUNEIFORM SIGN LAGAB TIMES DAR;Lo;0;L;;;;;N;;;;; +121C3;CUNEIFORM SIGN LAGAB TIMES EN;Lo;0;L;;;;;N;;;;; +121C4;CUNEIFORM SIGN LAGAB TIMES GA;Lo;0;L;;;;;N;;;;; +121C5;CUNEIFORM SIGN LAGAB TIMES GAR;Lo;0;L;;;;;N;;;;; +121C6;CUNEIFORM SIGN LAGAB TIMES GUD;Lo;0;L;;;;;N;;;;; +121C7;CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD;Lo;0;L;;;;;N;;;;; +121C8;CUNEIFORM SIGN LAGAB TIMES HA;Lo;0;L;;;;;N;;;;; +121C9;CUNEIFORM SIGN LAGAB TIMES HAL;Lo;0;L;;;;;N;;;;; +121CA;CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN;Lo;0;L;;;;;N;;;;; +121CB;CUNEIFORM SIGN LAGAB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +121CC;CUNEIFORM SIGN LAGAB TIMES IM;Lo;0;L;;;;;N;;;;; +121CD;CUNEIFORM SIGN LAGAB TIMES IM PLUS HA;Lo;0;L;;;;;N;;;;; +121CE;CUNEIFORM SIGN LAGAB TIMES IM PLUS LU;Lo;0;L;;;;;N;;;;; +121CF;CUNEIFORM SIGN LAGAB TIMES KI;Lo;0;L;;;;;N;;;;; +121D0;CUNEIFORM SIGN LAGAB TIMES KIN;Lo;0;L;;;;;N;;;;; +121D1;CUNEIFORM SIGN LAGAB TIMES KU3;Lo;0;L;;;;;N;;;;; +121D2;CUNEIFORM SIGN LAGAB TIMES KUL;Lo;0;L;;;;;N;;;;; +121D3;CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A;Lo;0;L;;;;;N;;;;; +121D4;CUNEIFORM SIGN LAGAB TIMES LAGAB;Lo;0;L;;;;;N;;;;; +121D5;CUNEIFORM SIGN LAGAB TIMES LISH;Lo;0;L;;;;;N;;;;; +121D6;CUNEIFORM SIGN LAGAB TIMES LU;Lo;0;L;;;;;N;;;;; +121D7;CUNEIFORM SIGN LAGAB TIMES LUL;Lo;0;L;;;;;N;;;;; +121D8;CUNEIFORM SIGN LAGAB TIMES ME;Lo;0;L;;;;;N;;;;; +121D9;CUNEIFORM SIGN LAGAB TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +121DA;CUNEIFORM SIGN LAGAB TIMES MUSH;Lo;0;L;;;;;N;;;;; +121DB;CUNEIFORM SIGN LAGAB TIMES NE;Lo;0;L;;;;;N;;;;; +121DC;CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;; +121DD;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2;Lo;0;L;;;;;N;;;;; +121DE;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU;Lo;0;L;;;;;N;;;;; +121DF;CUNEIFORM SIGN LAGAB TIMES SHU2;Lo;0;L;;;;;N;;;;; +121E0;CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2;Lo;0;L;;;;;N;;;;; +121E1;CUNEIFORM SIGN LAGAB TIMES SUM;Lo;0;L;;;;;N;;;;; +121E2;CUNEIFORM SIGN LAGAB TIMES TAG;Lo;0;L;;;;;N;;;;; +121E3;CUNEIFORM SIGN LAGAB TIMES TAK4;Lo;0;L;;;;;N;;;;; +121E4;CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA;Lo;0;L;;;;;N;;;;; +121E5;CUNEIFORM SIGN LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +121E6;CUNEIFORM SIGN LAGAB TIMES U PLUS A;Lo;0;L;;;;;N;;;;; +121E7;CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +121E8;CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +121E9;CUNEIFORM SIGN LAGAB TIMES UD;Lo;0;L;;;;;N;;;;; +121EA;CUNEIFORM SIGN LAGAB TIMES USH;Lo;0;L;;;;;N;;;;; +121EB;CUNEIFORM SIGN LAGAB SQUARED;Lo;0;L;;;;;N;;;;; +121EC;CUNEIFORM SIGN LAGAR;Lo;0;L;;;;;N;;;;; +121ED;CUNEIFORM SIGN LAGAR TIMES SHE;Lo;0;L;;;;;N;;;;; +121EE;CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;; +121EF;CUNEIFORM SIGN LAGAR GUNU;Lo;0;L;;;;;N;;;;; +121F0;CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE;Lo;0;L;;;;;N;;;;; +121F1;CUNEIFORM SIGN LAHSHU;Lo;0;L;;;;;N;;;;; +121F2;CUNEIFORM SIGN LAL;Lo;0;L;;;;;N;;;;; +121F3;CUNEIFORM SIGN LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +121F4;CUNEIFORM SIGN LAM;Lo;0;L;;;;;N;;;;; +121F5;CUNEIFORM SIGN LAM TIMES KUR;Lo;0;L;;;;;N;;;;; +121F6;CUNEIFORM SIGN LAM TIMES KUR PLUS RU;Lo;0;L;;;;;N;;;;; +121F7;CUNEIFORM SIGN LI;Lo;0;L;;;;;N;;;;; +121F8;CUNEIFORM SIGN LIL;Lo;0;L;;;;;N;;;;; +121F9;CUNEIFORM SIGN LIMMU2;Lo;0;L;;;;;N;;;;; +121FA;CUNEIFORM SIGN LISH;Lo;0;L;;;;;N;;;;; +121FB;CUNEIFORM SIGN LU;Lo;0;L;;;;;N;;;;; +121FC;CUNEIFORM SIGN LU TIMES BAD;Lo;0;L;;;;;N;;;;; +121FD;CUNEIFORM SIGN LU2;Lo;0;L;;;;;N;;;;; +121FE;CUNEIFORM SIGN LU2 TIMES AL;Lo;0;L;;;;;N;;;;; +121FF;CUNEIFORM SIGN LU2 TIMES BAD;Lo;0;L;;;;;N;;;;; +12200;CUNEIFORM SIGN LU2 TIMES ESH2;Lo;0;L;;;;;N;;;;; +12201;CUNEIFORM SIGN LU2 TIMES ESH2 TENU;Lo;0;L;;;;;N;;;;; +12202;CUNEIFORM SIGN LU2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12203;CUNEIFORM SIGN LU2 TIMES HI TIMES BAD;Lo;0;L;;;;;N;;;;; +12204;CUNEIFORM SIGN LU2 TIMES IM;Lo;0;L;;;;;N;;;;; +12205;CUNEIFORM SIGN LU2 TIMES KAD2;Lo;0;L;;;;;N;;;;; +12206;CUNEIFORM SIGN LU2 TIMES KAD3;Lo;0;L;;;;;N;;;;; +12207;CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH;Lo;0;L;;;;;N;;;;; +12208;CUNEIFORM SIGN LU2 TIMES KI;Lo;0;L;;;;;N;;;;; +12209;CUNEIFORM SIGN LU2 TIMES LA PLUS ASH;Lo;0;L;;;;;N;;;;; +1220A;CUNEIFORM SIGN LU2 TIMES LAGAB;Lo;0;L;;;;;N;;;;; +1220B;CUNEIFORM SIGN LU2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +1220C;CUNEIFORM SIGN LU2 TIMES NE;Lo;0;L;;;;;N;;;;; +1220D;CUNEIFORM SIGN LU2 TIMES NU;Lo;0;L;;;;;N;;;;; +1220E;CUNEIFORM SIGN LU2 TIMES SI PLUS ASH;Lo;0;L;;;;;N;;;;; +1220F;CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU;Lo;0;L;;;;;N;;;;; +12210;CUNEIFORM SIGN LU2 TIMES TUG2;Lo;0;L;;;;;N;;;;; +12211;CUNEIFORM SIGN LU2 TENU;Lo;0;L;;;;;N;;;;; +12212;CUNEIFORM SIGN LU2 CROSSING LU2;Lo;0;L;;;;;N;;;;; +12213;CUNEIFORM SIGN LU2 OPPOSING LU2;Lo;0;L;;;;;N;;;;; +12214;CUNEIFORM SIGN LU2 SQUARED;Lo;0;L;;;;;N;;;;; +12215;CUNEIFORM SIGN LU2 SHESHIG;Lo;0;L;;;;;N;;;;; +12216;CUNEIFORM SIGN LU3;Lo;0;L;;;;;N;;;;; +12217;CUNEIFORM SIGN LUGAL;Lo;0;L;;;;;N;;;;; +12218;CUNEIFORM SIGN LUGAL OVER LUGAL;Lo;0;L;;;;;N;;;;; +12219;CUNEIFORM SIGN LUGAL OPPOSING LUGAL;Lo;0;L;;;;;N;;;;; +1221A;CUNEIFORM SIGN LUGAL SHESHIG;Lo;0;L;;;;;N;;;;; +1221B;CUNEIFORM SIGN LUH;Lo;0;L;;;;;N;;;;; +1221C;CUNEIFORM SIGN LUL;Lo;0;L;;;;;N;;;;; +1221D;CUNEIFORM SIGN LUM;Lo;0;L;;;;;N;;;;; +1221E;CUNEIFORM SIGN LUM OVER LUM;Lo;0;L;;;;;N;;;;; +1221F;CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR;Lo;0;L;;;;;N;;;;; +12220;CUNEIFORM SIGN MA;Lo;0;L;;;;;N;;;;; +12221;CUNEIFORM SIGN MA TIMES TAK4;Lo;0;L;;;;;N;;;;; +12222;CUNEIFORM SIGN MA GUNU;Lo;0;L;;;;;N;;;;; +12223;CUNEIFORM SIGN MA2;Lo;0;L;;;;;N;;;;; +12224;CUNEIFORM SIGN MAH;Lo;0;L;;;;;N;;;;; +12225;CUNEIFORM SIGN MAR;Lo;0;L;;;;;N;;;;; +12226;CUNEIFORM SIGN MASH;Lo;0;L;;;;;N;;;;; +12227;CUNEIFORM SIGN MASH2;Lo;0;L;;;;;N;;;;; +12228;CUNEIFORM SIGN ME;Lo;0;L;;;;;N;;;;; +12229;CUNEIFORM SIGN MES;Lo;0;L;;;;;N;;;;; +1222A;CUNEIFORM SIGN MI;Lo;0;L;;;;;N;;;;; +1222B;CUNEIFORM SIGN MIN;Lo;0;L;;;;;N;;;;; +1222C;CUNEIFORM SIGN MU;Lo;0;L;;;;;N;;;;; +1222D;CUNEIFORM SIGN MU OVER MU;Lo;0;L;;;;;N;;;;; +1222E;CUNEIFORM SIGN MUG;Lo;0;L;;;;;N;;;;; +1222F;CUNEIFORM SIGN MUG GUNU;Lo;0;L;;;;;N;;;;; +12230;CUNEIFORM SIGN MUNSUB;Lo;0;L;;;;;N;;;;; +12231;CUNEIFORM SIGN MURGU2;Lo;0;L;;;;;N;;;;; +12232;CUNEIFORM SIGN MUSH;Lo;0;L;;;;;N;;;;; +12233;CUNEIFORM SIGN MUSH TIMES A;Lo;0;L;;;;;N;;;;; +12234;CUNEIFORM SIGN MUSH TIMES KUR;Lo;0;L;;;;;N;;;;; +12235;CUNEIFORM SIGN MUSH TIMES ZA;Lo;0;L;;;;;N;;;;; +12236;CUNEIFORM SIGN MUSH OVER MUSH;Lo;0;L;;;;;N;;;;; +12237;CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA;Lo;0;L;;;;;N;;;;; +12238;CUNEIFORM SIGN MUSH CROSSING MUSH;Lo;0;L;;;;;N;;;;; +12239;CUNEIFORM SIGN MUSH3;Lo;0;L;;;;;N;;;;; +1223A;CUNEIFORM SIGN MUSH3 TIMES A;Lo;0;L;;;;;N;;;;; +1223B;CUNEIFORM SIGN MUSH3 TIMES A PLUS DI;Lo;0;L;;;;;N;;;;; +1223C;CUNEIFORM SIGN MUSH3 TIMES DI;Lo;0;L;;;;;N;;;;; +1223D;CUNEIFORM SIGN MUSH3 GUNU;Lo;0;L;;;;;N;;;;; +1223E;CUNEIFORM SIGN NA;Lo;0;L;;;;;N;;;;; +1223F;CUNEIFORM SIGN NA2;Lo;0;L;;;;;N;;;;; +12240;CUNEIFORM SIGN NAGA;Lo;0;L;;;;;N;;;;; +12241;CUNEIFORM SIGN NAGA INVERTED;Lo;0;L;;;;;N;;;;; +12242;CUNEIFORM SIGN NAGA TIMES SHU TENU;Lo;0;L;;;;;N;;;;; +12243;CUNEIFORM SIGN NAGA OPPOSING NAGA;Lo;0;L;;;;;N;;;;; +12244;CUNEIFORM SIGN NAGAR;Lo;0;L;;;;;N;;;;; +12245;CUNEIFORM SIGN NAM NUTILLU;Lo;0;L;;;;;N;;;;; +12246;CUNEIFORM SIGN NAM;Lo;0;L;;;;;N;;;;; +12247;CUNEIFORM SIGN NAM2;Lo;0;L;;;;;N;;;;; +12248;CUNEIFORM SIGN NE;Lo;0;L;;;;;N;;;;; +12249;CUNEIFORM SIGN NE TIMES A;Lo;0;L;;;;;N;;;;; +1224A;CUNEIFORM SIGN NE TIMES UD;Lo;0;L;;;;;N;;;;; +1224B;CUNEIFORM SIGN NE SHESHIG;Lo;0;L;;;;;N;;;;; +1224C;CUNEIFORM SIGN NI;Lo;0;L;;;;;N;;;;; +1224D;CUNEIFORM SIGN NI TIMES E;Lo;0;L;;;;;N;;;;; +1224E;CUNEIFORM SIGN NI2;Lo;0;L;;;;;N;;;;; +1224F;CUNEIFORM SIGN NIM;Lo;0;L;;;;;N;;;;; +12250;CUNEIFORM SIGN NIM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12251;CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;; +12252;CUNEIFORM SIGN NINDA2;Lo;0;L;;;;;N;;;;; +12253;CUNEIFORM SIGN NINDA2 TIMES AN;Lo;0;L;;;;;N;;;;; +12254;CUNEIFORM SIGN NINDA2 TIMES ASH;Lo;0;L;;;;;N;;;;; +12255;CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH;Lo;0;L;;;;;N;;;;; +12256;CUNEIFORM SIGN NINDA2 TIMES GUD;Lo;0;L;;;;;N;;;;; +12257;CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;; +12258;CUNEIFORM SIGN NINDA2 TIMES NE;Lo;0;L;;;;;N;;;;; +12259;CUNEIFORM SIGN NINDA2 TIMES NUN;Lo;0;L;;;;;N;;;;; +1225A;CUNEIFORM SIGN NINDA2 TIMES SHE;Lo;0;L;;;;;N;;;;; +1225B;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN;Lo;0;L;;;;;N;;;;; +1225C;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH;Lo;0;L;;;;;N;;;;; +1225D;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH;Lo;0;L;;;;;N;;;;; +1225E;CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +1225F;CUNEIFORM SIGN NINDA2 TIMES USH;Lo;0;L;;;;;N;;;;; +12260;CUNEIFORM SIGN NISAG;Lo;0;L;;;;;N;;;;; +12261;CUNEIFORM SIGN NU;Lo;0;L;;;;;N;;;;; +12262;CUNEIFORM SIGN NU11;Lo;0;L;;;;;N;;;;; +12263;CUNEIFORM SIGN NUN;Lo;0;L;;;;;N;;;;; +12264;CUNEIFORM SIGN NUN LAGAR TIMES GAR;Lo;0;L;;;;;N;;;;; +12265;CUNEIFORM SIGN NUN LAGAR TIMES MASH;Lo;0;L;;;;;N;;;;; +12266;CUNEIFORM SIGN NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;; +12267;CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;; +12268;CUNEIFORM SIGN NUN LAGAR TIMES USH;Lo;0;L;;;;;N;;;;; +12269;CUNEIFORM SIGN NUN TENU;Lo;0;L;;;;;N;;;;; +1226A;CUNEIFORM SIGN NUN OVER NUN;Lo;0;L;;;;;N;;;;; +1226B;CUNEIFORM SIGN NUN CROSSING NUN;Lo;0;L;;;;;N;;;;; +1226C;CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR;Lo;0;L;;;;;N;;;;; +1226D;CUNEIFORM SIGN NUNUZ;Lo;0;L;;;;;N;;;;; +1226E;CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB;Lo;0;L;;;;;N;;;;; +1226F;CUNEIFORM SIGN NUNUZ AB2 TIMES BI;Lo;0;L;;;;;N;;;;; +12270;CUNEIFORM SIGN NUNUZ AB2 TIMES DUG;Lo;0;L;;;;;N;;;;; +12271;CUNEIFORM SIGN NUNUZ AB2 TIMES GUD;Lo;0;L;;;;;N;;;;; +12272;CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12273;CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3;Lo;0;L;;;;;N;;;;; +12274;CUNEIFORM SIGN NUNUZ AB2 TIMES LA;Lo;0;L;;;;;N;;;;; +12275;CUNEIFORM SIGN NUNUZ AB2 TIMES NE;Lo;0;L;;;;;N;;;;; +12276;CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3;Lo;0;L;;;;;N;;;;; +12277;CUNEIFORM SIGN NUNUZ AB2 TIMES U2;Lo;0;L;;;;;N;;;;; +12278;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;; +12279;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U;Lo;0;L;;;;;N;;;;; +1227A;CUNEIFORM SIGN PA;Lo;0;L;;;;;N;;;;; +1227B;CUNEIFORM SIGN PAD;Lo;0;L;;;;;N;;;;; +1227C;CUNEIFORM SIGN PAN;Lo;0;L;;;;;N;;;;; +1227D;CUNEIFORM SIGN PAP;Lo;0;L;;;;;N;;;;; +1227E;CUNEIFORM SIGN PESH2;Lo;0;L;;;;;N;;;;; +1227F;CUNEIFORM SIGN PI;Lo;0;L;;;;;N;;;;; +12280;CUNEIFORM SIGN PI TIMES A;Lo;0;L;;;;;N;;;;; +12281;CUNEIFORM SIGN PI TIMES AB;Lo;0;L;;;;;N;;;;; +12282;CUNEIFORM SIGN PI TIMES BI;Lo;0;L;;;;;N;;;;; +12283;CUNEIFORM SIGN PI TIMES BU;Lo;0;L;;;;;N;;;;; +12284;CUNEIFORM SIGN PI TIMES E;Lo;0;L;;;;;N;;;;; +12285;CUNEIFORM SIGN PI TIMES I;Lo;0;L;;;;;N;;;;; +12286;CUNEIFORM SIGN PI TIMES IB;Lo;0;L;;;;;N;;;;; +12287;CUNEIFORM SIGN PI TIMES U;Lo;0;L;;;;;N;;;;; +12288;CUNEIFORM SIGN PI TIMES U2;Lo;0;L;;;;;N;;;;; +12289;CUNEIFORM SIGN PI CROSSING PI;Lo;0;L;;;;;N;;;;; +1228A;CUNEIFORM SIGN PIRIG;Lo;0;L;;;;;N;;;;; +1228B;CUNEIFORM SIGN PIRIG TIMES KAL;Lo;0;L;;;;;N;;;;; +1228C;CUNEIFORM SIGN PIRIG TIMES UD;Lo;0;L;;;;;N;;;;; +1228D;CUNEIFORM SIGN PIRIG TIMES ZA;Lo;0;L;;;;;N;;;;; +1228E;CUNEIFORM SIGN PIRIG OPPOSING PIRIG;Lo;0;L;;;;;N;;;;; +1228F;CUNEIFORM SIGN RA;Lo;0;L;;;;;N;;;;; +12290;CUNEIFORM SIGN RAB;Lo;0;L;;;;;N;;;;; +12291;CUNEIFORM SIGN RI;Lo;0;L;;;;;N;;;;; +12292;CUNEIFORM SIGN RU;Lo;0;L;;;;;N;;;;; +12293;CUNEIFORM SIGN SA;Lo;0;L;;;;;N;;;;; +12294;CUNEIFORM SIGN SAG NUTILLU;Lo;0;L;;;;;N;;;;; +12295;CUNEIFORM SIGN SAG;Lo;0;L;;;;;N;;;;; +12296;CUNEIFORM SIGN SAG TIMES A;Lo;0;L;;;;;N;;;;; +12297;CUNEIFORM SIGN SAG TIMES DU;Lo;0;L;;;;;N;;;;; +12298;CUNEIFORM SIGN SAG TIMES DUB;Lo;0;L;;;;;N;;;;; +12299;CUNEIFORM SIGN SAG TIMES HA;Lo;0;L;;;;;N;;;;; +1229A;CUNEIFORM SIGN SAG TIMES KAK;Lo;0;L;;;;;N;;;;; +1229B;CUNEIFORM SIGN SAG TIMES KUR;Lo;0;L;;;;;N;;;;; +1229C;CUNEIFORM SIGN SAG TIMES LUM;Lo;0;L;;;;;N;;;;; +1229D;CUNEIFORM SIGN SAG TIMES MI;Lo;0;L;;;;;N;;;;; +1229E;CUNEIFORM SIGN SAG TIMES NUN;Lo;0;L;;;;;N;;;;; +1229F;CUNEIFORM SIGN SAG TIMES SAL;Lo;0;L;;;;;N;;;;; +122A0;CUNEIFORM SIGN SAG TIMES SHID;Lo;0;L;;;;;N;;;;; +122A1;CUNEIFORM SIGN SAG TIMES TAB;Lo;0;L;;;;;N;;;;; +122A2;CUNEIFORM SIGN SAG TIMES U2;Lo;0;L;;;;;N;;;;; +122A3;CUNEIFORM SIGN SAG TIMES UB;Lo;0;L;;;;;N;;;;; +122A4;CUNEIFORM SIGN SAG TIMES UM;Lo;0;L;;;;;N;;;;; +122A5;CUNEIFORM SIGN SAG TIMES UR;Lo;0;L;;;;;N;;;;; +122A6;CUNEIFORM SIGN SAG TIMES USH;Lo;0;L;;;;;N;;;;; +122A7;CUNEIFORM SIGN SAG OVER SAG;Lo;0;L;;;;;N;;;;; +122A8;CUNEIFORM SIGN SAG GUNU;Lo;0;L;;;;;N;;;;; +122A9;CUNEIFORM SIGN SAL;Lo;0;L;;;;;N;;;;; +122AA;CUNEIFORM SIGN SAL LAGAB TIMES ASH2;Lo;0;L;;;;;N;;;;; +122AB;CUNEIFORM SIGN SANGA2;Lo;0;L;;;;;N;;;;; +122AC;CUNEIFORM SIGN SAR;Lo;0;L;;;;;N;;;;; +122AD;CUNEIFORM SIGN SHA;Lo;0;L;;;;;N;;;;; +122AE;CUNEIFORM SIGN SHA3;Lo;0;L;;;;;N;;;;; +122AF;CUNEIFORM SIGN SHA3 TIMES A;Lo;0;L;;;;;N;;;;; +122B0;CUNEIFORM SIGN SHA3 TIMES BAD;Lo;0;L;;;;;N;;;;; +122B1;CUNEIFORM SIGN SHA3 TIMES GISH;Lo;0;L;;;;;N;;;;; +122B2;CUNEIFORM SIGN SHA3 TIMES NE;Lo;0;L;;;;;N;;;;; +122B3;CUNEIFORM SIGN SHA3 TIMES SHU2;Lo;0;L;;;;;N;;;;; +122B4;CUNEIFORM SIGN SHA3 TIMES TUR;Lo;0;L;;;;;N;;;;; +122B5;CUNEIFORM SIGN SHA3 TIMES U;Lo;0;L;;;;;N;;;;; +122B6;CUNEIFORM SIGN SHA3 TIMES U PLUS A;Lo;0;L;;;;;N;;;;; +122B7;CUNEIFORM SIGN SHA6;Lo;0;L;;;;;N;;;;; +122B8;CUNEIFORM SIGN SHAB6;Lo;0;L;;;;;N;;;;; +122B9;CUNEIFORM SIGN SHAR2;Lo;0;L;;;;;N;;;;; +122BA;CUNEIFORM SIGN SHE;Lo;0;L;;;;;N;;;;; +122BB;CUNEIFORM SIGN SHE HU;Lo;0;L;;;;;N;;;;; +122BC;CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +122BD;CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR;Lo;0;L;;;;;N;;;;; +122BE;CUNEIFORM SIGN SHEG9;Lo;0;L;;;;;N;;;;; +122BF;CUNEIFORM SIGN SHEN;Lo;0;L;;;;;N;;;;; +122C0;CUNEIFORM SIGN SHESH;Lo;0;L;;;;;N;;;;; +122C1;CUNEIFORM SIGN SHESH2;Lo;0;L;;;;;N;;;;; +122C2;CUNEIFORM SIGN SHESHLAM;Lo;0;L;;;;;N;;;;; +122C3;CUNEIFORM SIGN SHID;Lo;0;L;;;;;N;;;;; +122C4;CUNEIFORM SIGN SHID TIMES A;Lo;0;L;;;;;N;;;;; +122C5;CUNEIFORM SIGN SHID TIMES IM;Lo;0;L;;;;;N;;;;; +122C6;CUNEIFORM SIGN SHIM;Lo;0;L;;;;;N;;;;; +122C7;CUNEIFORM SIGN SHIM TIMES A;Lo;0;L;;;;;N;;;;; +122C8;CUNEIFORM SIGN SHIM TIMES BAL;Lo;0;L;;;;;N;;;;; +122C9;CUNEIFORM SIGN SHIM TIMES BULUG;Lo;0;L;;;;;N;;;;; +122CA;CUNEIFORM SIGN SHIM TIMES DIN;Lo;0;L;;;;;N;;;;; +122CB;CUNEIFORM SIGN SHIM TIMES GAR;Lo;0;L;;;;;N;;;;; +122CC;CUNEIFORM SIGN SHIM TIMES IGI;Lo;0;L;;;;;N;;;;; +122CD;CUNEIFORM SIGN SHIM TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +122CE;CUNEIFORM SIGN SHIM TIMES KUSHU2;Lo;0;L;;;;;N;;;;; +122CF;CUNEIFORM SIGN SHIM TIMES LUL;Lo;0;L;;;;;N;;;;; +122D0;CUNEIFORM SIGN SHIM TIMES MUG;Lo;0;L;;;;;N;;;;; +122D1;CUNEIFORM SIGN SHIM TIMES SAL;Lo;0;L;;;;;N;;;;; +122D2;CUNEIFORM SIGN SHINIG;Lo;0;L;;;;;N;;;;; +122D3;CUNEIFORM SIGN SHIR;Lo;0;L;;;;;N;;;;; +122D4;CUNEIFORM SIGN SHIR TENU;Lo;0;L;;;;;N;;;;; +122D5;CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR;Lo;0;L;;;;;N;;;;; +122D6;CUNEIFORM SIGN SHITA;Lo;0;L;;;;;N;;;;; +122D7;CUNEIFORM SIGN SHU;Lo;0;L;;;;;N;;;;; +122D8;CUNEIFORM SIGN SHU OVER INVERTED SHU;Lo;0;L;;;;;N;;;;; +122D9;CUNEIFORM SIGN SHU2;Lo;0;L;;;;;N;;;;; +122DA;CUNEIFORM SIGN SHUBUR;Lo;0;L;;;;;N;;;;; +122DB;CUNEIFORM SIGN SI;Lo;0;L;;;;;N;;;;; +122DC;CUNEIFORM SIGN SI GUNU;Lo;0;L;;;;;N;;;;; +122DD;CUNEIFORM SIGN SIG;Lo;0;L;;;;;N;;;;; +122DE;CUNEIFORM SIGN SIG4;Lo;0;L;;;;;N;;;;; +122DF;CUNEIFORM SIGN SIG4 OVER SIG4 SHU2;Lo;0;L;;;;;N;;;;; +122E0;CUNEIFORM SIGN SIK2;Lo;0;L;;;;;N;;;;; +122E1;CUNEIFORM SIGN SILA3;Lo;0;L;;;;;N;;;;; +122E2;CUNEIFORM SIGN SU;Lo;0;L;;;;;N;;;;; +122E3;CUNEIFORM SIGN SU OVER SU;Lo;0;L;;;;;N;;;;; +122E4;CUNEIFORM SIGN SUD;Lo;0;L;;;;;N;;;;; +122E5;CUNEIFORM SIGN SUD2;Lo;0;L;;;;;N;;;;; +122E6;CUNEIFORM SIGN SUHUR;Lo;0;L;;;;;N;;;;; +122E7;CUNEIFORM SIGN SUM;Lo;0;L;;;;;N;;;;; +122E8;CUNEIFORM SIGN SUMASH;Lo;0;L;;;;;N;;;;; +122E9;CUNEIFORM SIGN SUR;Lo;0;L;;;;;N;;;;; +122EA;CUNEIFORM SIGN SUR9;Lo;0;L;;;;;N;;;;; +122EB;CUNEIFORM SIGN TA;Lo;0;L;;;;;N;;;;; +122EC;CUNEIFORM SIGN TA ASTERISK;Lo;0;L;;;;;N;;;;; +122ED;CUNEIFORM SIGN TA TIMES HI;Lo;0;L;;;;;N;;;;; +122EE;CUNEIFORM SIGN TA TIMES MI;Lo;0;L;;;;;N;;;;; +122EF;CUNEIFORM SIGN TA GUNU;Lo;0;L;;;;;N;;;;; +122F0;CUNEIFORM SIGN TAB;Lo;0;L;;;;;N;;;;; +122F1;CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH;Lo;0;L;;;;;N;;;;; +122F2;CUNEIFORM SIGN TAB SQUARED;Lo;0;L;;;;;N;;;;; +122F3;CUNEIFORM SIGN TAG;Lo;0;L;;;;;N;;;;; +122F4;CUNEIFORM SIGN TAG TIMES BI;Lo;0;L;;;;;N;;;;; +122F5;CUNEIFORM SIGN TAG TIMES GUD;Lo;0;L;;;;;N;;;;; +122F6;CUNEIFORM SIGN TAG TIMES SHE;Lo;0;L;;;;;N;;;;; +122F7;CUNEIFORM SIGN TAG TIMES SHU;Lo;0;L;;;;;N;;;;; +122F8;CUNEIFORM SIGN TAG TIMES TUG2;Lo;0;L;;;;;N;;;;; +122F9;CUNEIFORM SIGN TAG TIMES UD;Lo;0;L;;;;;N;;;;; +122FA;CUNEIFORM SIGN TAK4;Lo;0;L;;;;;N;;;;; +122FB;CUNEIFORM SIGN TAR;Lo;0;L;;;;;N;;;;; +122FC;CUNEIFORM SIGN TE;Lo;0;L;;;;;N;;;;; +122FD;CUNEIFORM SIGN TE GUNU;Lo;0;L;;;;;N;;;;; +122FE;CUNEIFORM SIGN TI;Lo;0;L;;;;;N;;;;; +122FF;CUNEIFORM SIGN TI TENU;Lo;0;L;;;;;N;;;;; +12300;CUNEIFORM SIGN TIL;Lo;0;L;;;;;N;;;;; +12301;CUNEIFORM SIGN TIR;Lo;0;L;;;;;N;;;;; +12302;CUNEIFORM SIGN TIR TIMES TAK4;Lo;0;L;;;;;N;;;;; +12303;CUNEIFORM SIGN TIR OVER TIR;Lo;0;L;;;;;N;;;;; +12304;CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +12305;CUNEIFORM SIGN TU;Lo;0;L;;;;;N;;;;; +12306;CUNEIFORM SIGN TUG2;Lo;0;L;;;;;N;;;;; +12307;CUNEIFORM SIGN TUK;Lo;0;L;;;;;N;;;;; +12308;CUNEIFORM SIGN TUM;Lo;0;L;;;;;N;;;;; +12309;CUNEIFORM SIGN TUR;Lo;0;L;;;;;N;;;;; +1230A;CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA;Lo;0;L;;;;;N;;;;; +1230B;CUNEIFORM SIGN U;Lo;0;L;;;;;N;;;;; +1230C;CUNEIFORM SIGN U GUD;Lo;0;L;;;;;N;;;;; +1230D;CUNEIFORM SIGN U U U;Lo;0;L;;;;;N;;;;; +1230E;CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR;Lo;0;L;;;;;N;;;;; +1230F;CUNEIFORM SIGN U OVER U SUR OVER SUR;Lo;0;L;;;;;N;;;;; +12310;CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED;Lo;0;L;;;;;N;;;;; +12311;CUNEIFORM SIGN U2;Lo;0;L;;;;;N;;;;; +12312;CUNEIFORM SIGN UB;Lo;0;L;;;;;N;;;;; +12313;CUNEIFORM SIGN UD;Lo;0;L;;;;;N;;;;; +12314;CUNEIFORM SIGN UD KUSHU2;Lo;0;L;;;;;N;;;;; +12315;CUNEIFORM SIGN UD TIMES BAD;Lo;0;L;;;;;N;;;;; +12316;CUNEIFORM SIGN UD TIMES MI;Lo;0;L;;;;;N;;;;; +12317;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +12318;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU;Lo;0;L;;;;;N;;;;; +12319;CUNEIFORM SIGN UD GUNU;Lo;0;L;;;;;N;;;;; +1231A;CUNEIFORM SIGN UD SHESHIG;Lo;0;L;;;;;N;;;;; +1231B;CUNEIFORM SIGN UD SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;; +1231C;CUNEIFORM SIGN UDUG;Lo;0;L;;;;;N;;;;; +1231D;CUNEIFORM SIGN UM;Lo;0;L;;;;;N;;;;; +1231E;CUNEIFORM SIGN UM TIMES LAGAB;Lo;0;L;;;;;N;;;;; +1231F;CUNEIFORM SIGN UM TIMES ME PLUS DA;Lo;0;L;;;;;N;;;;; +12320;CUNEIFORM SIGN UM TIMES SHA3;Lo;0;L;;;;;N;;;;; +12321;CUNEIFORM SIGN UM TIMES U;Lo;0;L;;;;;N;;;;; +12322;CUNEIFORM SIGN UMBIN;Lo;0;L;;;;;N;;;;; +12323;CUNEIFORM SIGN UMUM;Lo;0;L;;;;;N;;;;; +12324;CUNEIFORM SIGN UMUM TIMES KASKAL;Lo;0;L;;;;;N;;;;; +12325;CUNEIFORM SIGN UMUM TIMES PA;Lo;0;L;;;;;N;;;;; +12326;CUNEIFORM SIGN UN;Lo;0;L;;;;;N;;;;; +12327;CUNEIFORM SIGN UN GUNU;Lo;0;L;;;;;N;;;;; +12328;CUNEIFORM SIGN UR;Lo;0;L;;;;;N;;;;; +12329;CUNEIFORM SIGN UR CROSSING UR;Lo;0;L;;;;;N;;;;; +1232A;CUNEIFORM SIGN UR SHESHIG;Lo;0;L;;;;;N;;;;; +1232B;CUNEIFORM SIGN UR2;Lo;0;L;;;;;N;;;;; +1232C;CUNEIFORM SIGN UR2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;; +1232D;CUNEIFORM SIGN UR2 TIMES A PLUS NA;Lo;0;L;;;;;N;;;;; +1232E;CUNEIFORM SIGN UR2 TIMES AL;Lo;0;L;;;;;N;;;;; +1232F;CUNEIFORM SIGN UR2 TIMES HA;Lo;0;L;;;;;N;;;;; +12330;CUNEIFORM SIGN UR2 TIMES NUN;Lo;0;L;;;;;N;;;;; +12331;CUNEIFORM SIGN UR2 TIMES U2;Lo;0;L;;;;;N;;;;; +12332;CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +12333;CUNEIFORM SIGN UR2 TIMES U2 PLUS BI;Lo;0;L;;;;;N;;;;; +12334;CUNEIFORM SIGN UR4;Lo;0;L;;;;;N;;;;; +12335;CUNEIFORM SIGN URI;Lo;0;L;;;;;N;;;;; +12336;CUNEIFORM SIGN URI3;Lo;0;L;;;;;N;;;;; +12337;CUNEIFORM SIGN URU;Lo;0;L;;;;;N;;;;; +12338;CUNEIFORM SIGN URU TIMES A;Lo;0;L;;;;;N;;;;; +12339;CUNEIFORM SIGN URU TIMES ASHGAB;Lo;0;L;;;;;N;;;;; +1233A;CUNEIFORM SIGN URU TIMES BAR;Lo;0;L;;;;;N;;;;; +1233B;CUNEIFORM SIGN URU TIMES DUN;Lo;0;L;;;;;N;;;;; +1233C;CUNEIFORM SIGN URU TIMES GA;Lo;0;L;;;;;N;;;;; +1233D;CUNEIFORM SIGN URU TIMES GAL;Lo;0;L;;;;;N;;;;; +1233E;CUNEIFORM SIGN URU TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1233F;CUNEIFORM SIGN URU TIMES GAR;Lo;0;L;;;;;N;;;;; +12340;CUNEIFORM SIGN URU TIMES GU;Lo;0;L;;;;;N;;;;; +12341;CUNEIFORM SIGN URU TIMES HA;Lo;0;L;;;;;N;;;;; +12342;CUNEIFORM SIGN URU TIMES IGI;Lo;0;L;;;;;N;;;;; +12343;CUNEIFORM SIGN URU TIMES IM;Lo;0;L;;;;;N;;;;; +12344;CUNEIFORM SIGN URU TIMES ISH;Lo;0;L;;;;;N;;;;; +12345;CUNEIFORM SIGN URU TIMES KI;Lo;0;L;;;;;N;;;;; +12346;CUNEIFORM SIGN URU TIMES LUM;Lo;0;L;;;;;N;;;;; +12347;CUNEIFORM SIGN URU TIMES MIN;Lo;0;L;;;;;N;;;;; +12348;CUNEIFORM SIGN URU TIMES PA;Lo;0;L;;;;;N;;;;; +12349;CUNEIFORM SIGN URU TIMES SHE;Lo;0;L;;;;;N;;;;; +1234A;CUNEIFORM SIGN URU TIMES SIG4;Lo;0;L;;;;;N;;;;; +1234B;CUNEIFORM SIGN URU TIMES TU;Lo;0;L;;;;;N;;;;; +1234C;CUNEIFORM SIGN URU TIMES U PLUS GUD;Lo;0;L;;;;;N;;;;; +1234D;CUNEIFORM SIGN URU TIMES UD;Lo;0;L;;;;;N;;;;; +1234E;CUNEIFORM SIGN URU TIMES URUDA;Lo;0;L;;;;;N;;;;; +1234F;CUNEIFORM SIGN URUDA;Lo;0;L;;;;;N;;;;; +12350;CUNEIFORM SIGN URUDA TIMES U;Lo;0;L;;;;;N;;;;; +12351;CUNEIFORM SIGN USH;Lo;0;L;;;;;N;;;;; +12352;CUNEIFORM SIGN USH TIMES A;Lo;0;L;;;;;N;;;;; +12353;CUNEIFORM SIGN USH TIMES KU;Lo;0;L;;;;;N;;;;; +12354;CUNEIFORM SIGN USH TIMES KUR;Lo;0;L;;;;;N;;;;; +12355;CUNEIFORM SIGN USH TIMES TAK4;Lo;0;L;;;;;N;;;;; +12356;CUNEIFORM SIGN USHX;Lo;0;L;;;;;N;;;;; +12357;CUNEIFORM SIGN USH2;Lo;0;L;;;;;N;;;;; +12358;CUNEIFORM SIGN USHUMX;Lo;0;L;;;;;N;;;;; +12359;CUNEIFORM SIGN UTUKI;Lo;0;L;;;;;N;;;;; +1235A;CUNEIFORM SIGN UZ3;Lo;0;L;;;;;N;;;;; +1235B;CUNEIFORM SIGN UZ3 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +1235C;CUNEIFORM SIGN UZU;Lo;0;L;;;;;N;;;;; +1235D;CUNEIFORM SIGN ZA;Lo;0;L;;;;;N;;;;; +1235E;CUNEIFORM SIGN ZA TENU;Lo;0;L;;;;;N;;;;; +1235F;CUNEIFORM SIGN ZA SQUARED TIMES KUR;Lo;0;L;;;;;N;;;;; +12360;CUNEIFORM SIGN ZAG;Lo;0;L;;;;;N;;;;; +12361;CUNEIFORM SIGN ZAMX;Lo;0;L;;;;;N;;;;; +12362;CUNEIFORM SIGN ZE2;Lo;0;L;;;;;N;;;;; +12363;CUNEIFORM SIGN ZI;Lo;0;L;;;;;N;;;;; +12364;CUNEIFORM SIGN ZI OVER ZI;Lo;0;L;;;;;N;;;;; +12365;CUNEIFORM SIGN ZI3;Lo;0;L;;;;;N;;;;; +12366;CUNEIFORM SIGN ZIB;Lo;0;L;;;;;N;;;;; +12367;CUNEIFORM SIGN ZIB KABA TENU;Lo;0;L;;;;;N;;;;; +12368;CUNEIFORM SIGN ZIG;Lo;0;L;;;;;N;;;;; +12369;CUNEIFORM SIGN ZIZ2;Lo;0;L;;;;;N;;;;; +1236A;CUNEIFORM SIGN ZU;Lo;0;L;;;;;N;;;;; +1236B;CUNEIFORM SIGN ZU5;Lo;0;L;;;;;N;;;;; +1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;; +1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;; +1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;; +12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;; +12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;; +12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;; +12403;CUNEIFORM NUMERIC SIGN FIVE ASH;Nl;0;L;;;;5;N;;;;; +12404;CUNEIFORM NUMERIC SIGN SIX ASH;Nl;0;L;;;;6;N;;;;; +12405;CUNEIFORM NUMERIC SIGN SEVEN ASH;Nl;0;L;;;;7;N;;;;; +12406;CUNEIFORM NUMERIC SIGN EIGHT ASH;Nl;0;L;;;;8;N;;;;; +12407;CUNEIFORM NUMERIC SIGN NINE ASH;Nl;0;L;;;;9;N;;;;; +12408;CUNEIFORM NUMERIC SIGN THREE DISH;Nl;0;L;;;;3;N;;;;; +12409;CUNEIFORM NUMERIC SIGN FOUR DISH;Nl;0;L;;;;4;N;;;;; +1240A;CUNEIFORM NUMERIC SIGN FIVE DISH;Nl;0;L;;;;5;N;;;;; +1240B;CUNEIFORM NUMERIC SIGN SIX DISH;Nl;0;L;;;;6;N;;;;; +1240C;CUNEIFORM NUMERIC SIGN SEVEN DISH;Nl;0;L;;;;7;N;;;;; +1240D;CUNEIFORM NUMERIC SIGN EIGHT DISH;Nl;0;L;;;;8;N;;;;; +1240E;CUNEIFORM NUMERIC SIGN NINE DISH;Nl;0;L;;;;9;N;;;;; +1240F;CUNEIFORM NUMERIC SIGN FOUR U;Nl;0;L;;;;4;N;;;;; +12410;CUNEIFORM NUMERIC SIGN FIVE U;Nl;0;L;;;;5;N;;;;; +12411;CUNEIFORM NUMERIC SIGN SIX U;Nl;0;L;;;;6;N;;;;; +12412;CUNEIFORM NUMERIC SIGN SEVEN U;Nl;0;L;;;;7;N;;;;; +12413;CUNEIFORM NUMERIC SIGN EIGHT U;Nl;0;L;;;;8;N;;;;; +12414;CUNEIFORM NUMERIC SIGN NINE U;Nl;0;L;;;;9;N;;;;; +12415;CUNEIFORM NUMERIC SIGN ONE GESH2;Nl;0;L;;;;1;N;;;;; +12416;CUNEIFORM NUMERIC SIGN TWO GESH2;Nl;0;L;;;;2;N;;;;; +12417;CUNEIFORM NUMERIC SIGN THREE GESH2;Nl;0;L;;;;3;N;;;;; +12418;CUNEIFORM NUMERIC SIGN FOUR GESH2;Nl;0;L;;;;4;N;;;;; +12419;CUNEIFORM NUMERIC SIGN FIVE GESH2;Nl;0;L;;;;5;N;;;;; +1241A;CUNEIFORM NUMERIC SIGN SIX GESH2;Nl;0;L;;;;6;N;;;;; +1241B;CUNEIFORM NUMERIC SIGN SEVEN GESH2;Nl;0;L;;;;7;N;;;;; +1241C;CUNEIFORM NUMERIC SIGN EIGHT GESH2;Nl;0;L;;;;8;N;;;;; +1241D;CUNEIFORM NUMERIC SIGN NINE GESH2;Nl;0;L;;;;9;N;;;;; +1241E;CUNEIFORM NUMERIC SIGN ONE GESHU;Nl;0;L;;;;1;N;;;;; +1241F;CUNEIFORM NUMERIC SIGN TWO GESHU;Nl;0;L;;;;2;N;;;;; +12420;CUNEIFORM NUMERIC SIGN THREE GESHU;Nl;0;L;;;;3;N;;;;; +12421;CUNEIFORM NUMERIC SIGN FOUR GESHU;Nl;0;L;;;;4;N;;;;; +12422;CUNEIFORM NUMERIC SIGN FIVE GESHU;Nl;0;L;;;;5;N;;;;; +12423;CUNEIFORM NUMERIC SIGN TWO SHAR2;Nl;0;L;;;;2;N;;;;; +12424;CUNEIFORM NUMERIC SIGN THREE SHAR2;Nl;0;L;;;;3;N;;;;; +12425;CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12426;CUNEIFORM NUMERIC SIGN FOUR SHAR2;Nl;0;L;;;;4;N;;;;; +12427;CUNEIFORM NUMERIC SIGN FIVE SHAR2;Nl;0;L;;;;5;N;;;;; +12428;CUNEIFORM NUMERIC SIGN SIX SHAR2;Nl;0;L;;;;6;N;;;;; +12429;CUNEIFORM NUMERIC SIGN SEVEN SHAR2;Nl;0;L;;;;7;N;;;;; +1242A;CUNEIFORM NUMERIC SIGN EIGHT SHAR2;Nl;0;L;;;;8;N;;;;; +1242B;CUNEIFORM NUMERIC SIGN NINE SHAR2;Nl;0;L;;;;9;N;;;;; +1242C;CUNEIFORM NUMERIC SIGN ONE SHARU;Nl;0;L;;;;1;N;;;;; +1242D;CUNEIFORM NUMERIC SIGN TWO SHARU;Nl;0;L;;;;2;N;;;;; +1242E;CUNEIFORM NUMERIC SIGN THREE SHARU;Nl;0;L;;;;3;N;;;;; +1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;; +12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;; +12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;;N;;;;; +12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;;N;;;;; +12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;; +12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;; +12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;; +12437;CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12438;CUNEIFORM NUMERIC SIGN FOUR BURU;Nl;0;L;;;;4;N;;;;; +12439;CUNEIFORM NUMERIC SIGN FIVE BURU;Nl;0;L;;;;5;N;;;;; +1243A;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16;Nl;0;L;;;;3;N;;;;; +1243B;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21;Nl;0;L;;;;3;N;;;;; +1243C;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU;Nl;0;L;;;;4;N;;;;; +1243D;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4;Nl;0;L;;;;4;N;;;;; +1243E;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A;Nl;0;L;;;;4;N;;;;; +1243F;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B;Nl;0;L;;;;4;N;;;;; +12440;CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9;Nl;0;L;;;;6;N;;;;; +12441;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3;Nl;0;L;;;;7;N;;;;; +12442;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A;Nl;0;L;;;;7;N;;;;; +12443;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B;Nl;0;L;;;;7;N;;;;; +12444;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU;Nl;0;L;;;;8;N;;;;; +12445;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3;Nl;0;L;;;;8;N;;;;; +12446;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU;Nl;0;L;;;;9;N;;;;; +12447;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3;Nl;0;L;;;;9;N;;;;; +12448;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4;Nl;0;L;;;;9;N;;;;; +12449;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A;Nl;0;L;;;;9;N;;;;; +1244A;CUNEIFORM NUMERIC SIGN TWO ASH TENU;Nl;0;L;;;;2;N;;;;; +1244B;CUNEIFORM NUMERIC SIGN THREE ASH TENU;Nl;0;L;;;;3;N;;;;; +1244C;CUNEIFORM NUMERIC SIGN FOUR ASH TENU;Nl;0;L;;;;4;N;;;;; +1244D;CUNEIFORM NUMERIC SIGN FIVE ASH TENU;Nl;0;L;;;;5;N;;;;; +1244E;CUNEIFORM NUMERIC SIGN SIX ASH TENU;Nl;0;L;;;;6;N;;;;; +1244F;CUNEIFORM NUMERIC SIGN ONE BAN2;Nl;0;L;;;;1;N;;;;; +12450;CUNEIFORM NUMERIC SIGN TWO BAN2;Nl;0;L;;;;2;N;;;;; +12451;CUNEIFORM NUMERIC SIGN THREE BAN2;Nl;0;L;;;;3;N;;;;; +12452;CUNEIFORM NUMERIC SIGN FOUR BAN2;Nl;0;L;;;;4;N;;;;; +12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;; +12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;; +12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;; +12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;;N;;;;; +12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;;N;;;;; +12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;; +12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;; +1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;; +1245B;CUNEIFORM NUMERIC SIGN TWO THIRDS DISH;Nl;0;L;;;;2/3;N;;;;; +1245C;CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH;Nl;0;L;;;;5/6;N;;;;; +1245D;CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A;Nl;0;L;;;;1/3;N;;;;; +1245E;CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A;Nl;0;L;;;;2/3;N;;;;; +1245F;CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH;Nl;0;L;;;;1/8;N;;;;; +12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;; +12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;; +12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;; +12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;; +12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;; +12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;; +12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;; +1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;; +1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;; +1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;; +1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;; +1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;; +1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;; +1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;; +1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;; +1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;; +1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;; +1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;; +1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;; +1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;; +1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;; +1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;; +1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;; +1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;; +1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;; +1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;; +1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;; +1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;; +1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;; +1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;; +1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;; +1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;; +1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;; +1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;; +1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;; +1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;; +1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;; +1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;; +1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;; +1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;; +1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;; +1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;; +1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;; +1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;; +1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;; +1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;; +1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;; +1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;; +1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;; +1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;; +1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;; +1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;; +1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;; +1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;; +1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;; +1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;; +1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;; +1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;; +1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;; +1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;; +1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;; +1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;; +1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;; +1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;; +1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;; +1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;; +1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;; +1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;; +1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;; +1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;; +1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;; +1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;; +1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;; +1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;; +1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;; +1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;; +1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;; +1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;; +1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;; +1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;; +1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;; +1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;; +1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;; +1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;; +1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;; +1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;; +1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;; +1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;; +1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;; +1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;; +1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;; +1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;; +1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;; +1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;; +1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;; +1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;; +1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;; +1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;; +1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;; +1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;; +1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;; +1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;; +1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;; +1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;; +1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;; +1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;; +1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;; +1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;; +1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;; +1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;; +1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;; +1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;; +1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;; +1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;; +1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;; +1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;; +1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;; +1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;; +1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;; +1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;; +1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;; +1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;; +1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;; +1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;; +1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;; +1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;; +1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;; +1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;; +1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;; +1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;; +1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;; +1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;; +1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;; +1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;; +1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;; +1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;; +1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;; +1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;; +1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;; +1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;; +1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;; +1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;; +1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;; +1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;; +1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;; +1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;; +1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;; +1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;; +1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;; +1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;; +1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;; +1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;; +1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;; +1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;; +1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;; +1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;; +1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;; +1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;; +1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;; +1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;; +1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;; +1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;; +1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;; +1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;; +1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;; +1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;; +1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;; +1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;; +1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;; +1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;; +1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;; +1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;; +1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;; +1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;; +1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;; +1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;; +1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;; +1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;; +1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;; +1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;; +1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;; +1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;; +1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;; +1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;; +1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;; +1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;; +1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;; +1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;; +1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;; +1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;; +1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;; +1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;; +1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;; +1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;; +1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;; +1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;; +1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;; +1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;; +1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;; +1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;; +1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;; +1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;; +1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;; +1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;; +1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;; +1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;; +1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;; +1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;; +1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;; +1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;; +1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;; +1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;; +1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;; +1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;; +1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;; +1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;; +1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;; +1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;; +1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;; +1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;; +1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;; +1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;; +1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;; +1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;; +1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;; +1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;; +1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;; +1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;; +1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;; +1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;; +1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;; +1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;; +1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;; +1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;; +1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;; +1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;; +1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;; +1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;; +1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;; +1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;; +1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;; +1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;; +1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;; +1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;; +1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;; +1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;; +1D129;MUSICAL SYMBOL MULTIPLE MEASURE REST;So;0;L;;;;;N;;;;; +1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;; +1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;; +1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;; +1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;; +1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;; +1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;; +1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;; +1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;; +1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;; +1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;; +1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;; +1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;; +1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;; +1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;; +1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;; +1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;; +1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;; +1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;; +1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;; +1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;; +1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;; +1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;; +1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;; +1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;; +1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;; +1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;; +1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;; +1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;; +1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;; +1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;; +1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;; +1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;; +1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;; +1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;; +1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;; +1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;; +1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;; +1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;; +1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;; +1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;; +1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;; +1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;; +1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;; +1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;; +1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;; +1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;; +1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;; +1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;; +1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;; +1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;; +1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;; +1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;; +1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;; +1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;; +1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;; +1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;; +1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;; +1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;; +1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;; +1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;; +1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;; +1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;; +1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;; +1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;; +1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;; +1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;; +1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;; +1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;; +1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;; +1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;; +1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;; +1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;; +1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;; +1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;; +1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;; +1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;; +1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;; +1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;; +1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;; +1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;; +1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;; +1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;; +1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;; +1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;; +1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;; +1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;; +1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;; +1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;; +1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;; +1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;; +1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;; +1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;; +1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;; +1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;; +1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;; +1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;; +1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;; +1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;; +1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;; +1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;; +1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;; +1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;; +1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;; +1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;; +1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;; +1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;; +1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;; +1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;; +1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;; +1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;; +1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;; +1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;; +1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;; +1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;; +1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;; +1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;; +1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;; +1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;; +1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;; +1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;; +1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;; +1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;; +1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;; +1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;; +1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;; +1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;; +1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;; +1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;; +1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;; +1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;; +1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;; +1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;; +1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;; +1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;; +1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;; +1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;; +1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;; +1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;; +1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;; +1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;; +1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;; +1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;; +1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;; +1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;; +1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;; +1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;; +1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;; +1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;; +1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;; +1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;; +1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;; +1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;; +1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;; +1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;; +1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;; +1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;; +1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;; +1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;; +1D203;GREEK VOCAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;; +1D204;GREEK VOCAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;; +1D205;GREEK VOCAL NOTATION SYMBOL-6;So;0;ON;;;;;N;;;;; +1D206;GREEK VOCAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;; +1D207;GREEK VOCAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;; +1D208;GREEK VOCAL NOTATION SYMBOL-9;So;0;ON;;;;;N;;;;; +1D209;GREEK VOCAL NOTATION SYMBOL-10;So;0;ON;;;;;N;;;;; +1D20A;GREEK VOCAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;; +1D20B;GREEK VOCAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;; +1D20C;GREEK VOCAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;; +1D20D;GREEK VOCAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;; +1D20E;GREEK VOCAL NOTATION SYMBOL-15;So;0;ON;;;;;N;;;;; +1D20F;GREEK VOCAL NOTATION SYMBOL-16;So;0;ON;;;;;N;;;;; +1D210;GREEK VOCAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;; +1D211;GREEK VOCAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;; +1D212;GREEK VOCAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;; +1D213;GREEK VOCAL NOTATION SYMBOL-20;So;0;ON;;;;;N;;;;; +1D214;GREEK VOCAL NOTATION SYMBOL-21;So;0;ON;;;;;N;;;;; +1D215;GREEK VOCAL NOTATION SYMBOL-22;So;0;ON;;;;;N;;;;; +1D216;GREEK VOCAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;; +1D217;GREEK VOCAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;; +1D218;GREEK VOCAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;; +1D219;GREEK VOCAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;; +1D21A;GREEK VOCAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;; +1D21B;GREEK VOCAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;; +1D21C;GREEK VOCAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;; +1D21D;GREEK INSTRUMENTAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;; +1D21E;GREEK INSTRUMENTAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;; +1D21F;GREEK INSTRUMENTAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;; +1D220;GREEK INSTRUMENTAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;; +1D221;GREEK INSTRUMENTAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;; +1D222;GREEK INSTRUMENTAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;; +1D223;GREEK INSTRUMENTAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;; +1D224;GREEK INSTRUMENTAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;; +1D225;GREEK INSTRUMENTAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;; +1D226;GREEK INSTRUMENTAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;; +1D227;GREEK INSTRUMENTAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;; +1D228;GREEK INSTRUMENTAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;; +1D229;GREEK INSTRUMENTAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;; +1D22A;GREEK INSTRUMENTAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;; +1D22B;GREEK INSTRUMENTAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;; +1D22C;GREEK INSTRUMENTAL NOTATION SYMBOL-25;So;0;ON;;;;;N;;;;; +1D22D;GREEK INSTRUMENTAL NOTATION SYMBOL-26;So;0;ON;;;;;N;;;;; +1D22E;GREEK INSTRUMENTAL NOTATION SYMBOL-27;So;0;ON;;;;;N;;;;; +1D22F;GREEK INSTRUMENTAL NOTATION SYMBOL-29;So;0;ON;;;;;N;;;;; +1D230;GREEK INSTRUMENTAL NOTATION SYMBOL-30;So;0;ON;;;;;N;;;;; +1D231;GREEK INSTRUMENTAL NOTATION SYMBOL-32;So;0;ON;;;;;N;;;;; +1D232;GREEK INSTRUMENTAL NOTATION SYMBOL-36;So;0;ON;;;;;N;;;;; +1D233;GREEK INSTRUMENTAL NOTATION SYMBOL-37;So;0;ON;;;;;N;;;;; +1D234;GREEK INSTRUMENTAL NOTATION SYMBOL-38;So;0;ON;;;;;N;;;;; +1D235;GREEK INSTRUMENTAL NOTATION SYMBOL-39;So;0;ON;;;;;N;;;;; +1D236;GREEK INSTRUMENTAL NOTATION SYMBOL-40;So;0;ON;;;;;N;;;;; +1D237;GREEK INSTRUMENTAL NOTATION SYMBOL-42;So;0;ON;;;;;N;;;;; +1D238;GREEK INSTRUMENTAL NOTATION SYMBOL-43;So;0;ON;;;;;N;;;;; +1D239;GREEK INSTRUMENTAL NOTATION SYMBOL-45;So;0;ON;;;;;N;;;;; +1D23A;GREEK INSTRUMENTAL NOTATION SYMBOL-47;So;0;ON;;;;;N;;;;; +1D23B;GREEK INSTRUMENTAL NOTATION SYMBOL-48;So;0;ON;;;;;N;;;;; +1D23C;GREEK INSTRUMENTAL NOTATION SYMBOL-49;So;0;ON;;;;;N;;;;; +1D23D;GREEK INSTRUMENTAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;; +1D23E;GREEK INSTRUMENTAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;; +1D23F;GREEK INSTRUMENTAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;; +1D240;GREEK INSTRUMENTAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;; +1D241;GREEK INSTRUMENTAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;; +1D242;COMBINING GREEK MUSICAL TRISEME;Mn;230;NSM;;;;;N;;;;; +1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;; +1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;; +1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;; +1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;ren *;;; +1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;tian ren *;;; +1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;di ren *;;; +1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;ren tian *;;; +1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;ren di *;;; +1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;ren ren *;;; +1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;; +1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;; +1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;; +1D309;TETRAGRAM FOR BARRIER;So;0;ON;;;;;N;;;;; +1D30A;TETRAGRAM FOR KEEPING SMALL;So;0;ON;;;;;N;;;;; +1D30B;TETRAGRAM FOR CONTRARIETY;So;0;ON;;;;;N;;;;; +1D30C;TETRAGRAM FOR ASCENT;So;0;ON;;;;;N;;;;; +1D30D;TETRAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;; +1D30E;TETRAGRAM FOR BRANCHING OUT;So;0;ON;;;;;N;;;;; +1D30F;TETRAGRAM FOR DEFECTIVENESS OR DISTORTION;So;0;ON;;;;;N;;;;; +1D310;TETRAGRAM FOR DIVERGENCE;So;0;ON;;;;;N;;;;; +1D311;TETRAGRAM FOR YOUTHFULNESS;So;0;ON;;;;;N;;;;; +1D312;TETRAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;; +1D313;TETRAGRAM FOR PENETRATION;So;0;ON;;;;;N;;;;; +1D314;TETRAGRAM FOR REACH;So;0;ON;;;;;N;;;;; +1D315;TETRAGRAM FOR CONTACT;So;0;ON;;;;;N;;;;; +1D316;TETRAGRAM FOR HOLDING BACK;So;0;ON;;;;;N;;;;; +1D317;TETRAGRAM FOR WAITING;So;0;ON;;;;;N;;;;; +1D318;TETRAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;; +1D319;TETRAGRAM FOR ADVANCE;So;0;ON;;;;;N;;;;; +1D31A;TETRAGRAM FOR RELEASE;So;0;ON;;;;;N;;;;; +1D31B;TETRAGRAM FOR RESISTANCE;So;0;ON;;;;;N;;;;; +1D31C;TETRAGRAM FOR EASE;So;0;ON;;;;;N;;;;; +1D31D;TETRAGRAM FOR JOY;So;0;ON;;;;;N;;;;; +1D31E;TETRAGRAM FOR CONTENTION;So;0;ON;;;;;N;;;;; +1D31F;TETRAGRAM FOR ENDEAVOUR;So;0;ON;;;;;N;;;;; +1D320;TETRAGRAM FOR DUTIES;So;0;ON;;;;;N;;;;; +1D321;TETRAGRAM FOR CHANGE;So;0;ON;;;;;N;;;;; +1D322;TETRAGRAM FOR DECISIVENESS;So;0;ON;;;;;N;;;;; +1D323;TETRAGRAM FOR BOLD RESOLUTION;So;0;ON;;;;;N;;;;; +1D324;TETRAGRAM FOR PACKING;So;0;ON;;;;;N;;;;; +1D325;TETRAGRAM FOR LEGION;So;0;ON;;;;;N;;;;; +1D326;TETRAGRAM FOR CLOSENESS;So;0;ON;;;;;N;;;;; +1D327;TETRAGRAM FOR KINSHIP;So;0;ON;;;;;N;;;;; +1D328;TETRAGRAM FOR GATHERING;So;0;ON;;;;;N;;;;; +1D329;TETRAGRAM FOR STRENGTH;So;0;ON;;;;;N;;;;; +1D32A;TETRAGRAM FOR PURITY;So;0;ON;;;;;N;;;;; +1D32B;TETRAGRAM FOR FULLNESS;So;0;ON;;;;;N;;;;; +1D32C;TETRAGRAM FOR RESIDENCE;So;0;ON;;;;;N;;;;; +1D32D;TETRAGRAM FOR LAW OR MODEL;So;0;ON;;;;;N;;;;; +1D32E;TETRAGRAM FOR RESPONSE;So;0;ON;;;;;N;;;;; +1D32F;TETRAGRAM FOR GOING TO MEET;So;0;ON;;;;;N;;;;; +1D330;TETRAGRAM FOR ENCOUNTERS;So;0;ON;;;;;N;;;;; +1D331;TETRAGRAM FOR STOVE;So;0;ON;;;;;N;;;;; +1D332;TETRAGRAM FOR GREATNESS;So;0;ON;;;;;N;;;;; +1D333;TETRAGRAM FOR ENLARGEMENT;So;0;ON;;;;;N;;;;; +1D334;TETRAGRAM FOR PATTERN;So;0;ON;;;;;N;;;;; +1D335;TETRAGRAM FOR RITUAL;So;0;ON;;;;;N;;;;; +1D336;TETRAGRAM FOR FLIGHT;So;0;ON;;;;;N;;;;; +1D337;TETRAGRAM FOR VASTNESS OR WASTING;So;0;ON;;;;;N;;;;; +1D338;TETRAGRAM FOR CONSTANCY;So;0;ON;;;;;N;;;;; +1D339;TETRAGRAM FOR MEASURE;So;0;ON;;;;;N;;;;; +1D33A;TETRAGRAM FOR ETERNITY;So;0;ON;;;;;N;;;;; +1D33B;TETRAGRAM FOR UNITY;So;0;ON;;;;;N;;;;; +1D33C;TETRAGRAM FOR DIMINISHMENT;So;0;ON;;;;;N;;;;; +1D33D;TETRAGRAM FOR CLOSED MOUTH;So;0;ON;;;;;N;;;;; +1D33E;TETRAGRAM FOR GUARDEDNESS;So;0;ON;;;;;N;;;;; +1D33F;TETRAGRAM FOR GATHERING IN;So;0;ON;;;;;N;;;;; +1D340;TETRAGRAM FOR MASSING;So;0;ON;;;;;N;;;;; +1D341;TETRAGRAM FOR ACCUMULATION;So;0;ON;;;;;N;;;;; +1D342;TETRAGRAM FOR EMBELLISHMENT;So;0;ON;;;;;N;;;;; +1D343;TETRAGRAM FOR DOUBT;So;0;ON;;;;;N;;;;; +1D344;TETRAGRAM FOR WATCH;So;0;ON;;;;;N;;;;; +1D345;TETRAGRAM FOR SINKING;So;0;ON;;;;;N;;;;; +1D346;TETRAGRAM FOR INNER;So;0;ON;;;;;N;;;;; +1D347;TETRAGRAM FOR DEPARTURE;So;0;ON;;;;;N;;;;; +1D348;TETRAGRAM FOR DARKENING;So;0;ON;;;;;N;;;;; +1D349;TETRAGRAM FOR DIMMING;So;0;ON;;;;;N;;;;; +1D34A;TETRAGRAM FOR EXHAUSTION;So;0;ON;;;;;N;;;;; +1D34B;TETRAGRAM FOR SEVERANCE;So;0;ON;;;;;N;;;;; +1D34C;TETRAGRAM FOR STOPPAGE;So;0;ON;;;;;N;;;;; +1D34D;TETRAGRAM FOR HARDNESS;So;0;ON;;;;;N;;;;; +1D34E;TETRAGRAM FOR COMPLETION;So;0;ON;;;;;N;;;;; +1D34F;TETRAGRAM FOR CLOSURE;So;0;ON;;;;;N;;;;; +1D350;TETRAGRAM FOR FAILURE;So;0;ON;;;;;N;;;;; +1D351;TETRAGRAM FOR AGGRAVATION;So;0;ON;;;;;N;;;;; +1D352;TETRAGRAM FOR COMPLIANCE;So;0;ON;;;;;N;;;;; +1D353;TETRAGRAM FOR ON THE VERGE;So;0;ON;;;;;N;;;;; +1D354;TETRAGRAM FOR DIFFICULTIES;So;0;ON;;;;;N;;;;; +1D355;TETRAGRAM FOR LABOURING;So;0;ON;;;;;N;;;;; +1D356;TETRAGRAM FOR FOSTERING;So;0;ON;;;;;N;;;;; +1D360;COUNTING ROD UNIT DIGIT ONE;No;0;L;;;;1;N;;;;; +1D361;COUNTING ROD UNIT DIGIT TWO;No;0;L;;;;2;N;;;;; +1D362;COUNTING ROD UNIT DIGIT THREE;No;0;L;;;;3;N;;;;; +1D363;COUNTING ROD UNIT DIGIT FOUR;No;0;L;;;;4;N;;;;; +1D364;COUNTING ROD UNIT DIGIT FIVE;No;0;L;;;;5;N;;;;; +1D365;COUNTING ROD UNIT DIGIT SIX;No;0;L;;;;6;N;;;;; +1D366;COUNTING ROD UNIT DIGIT SEVEN;No;0;L;;;;7;N;;;;; +1D367;COUNTING ROD UNIT DIGIT EIGHT;No;0;L;;;;8;N;;;;; +1D368;COUNTING ROD UNIT DIGIT NINE;No;0;L;;;;9;N;;;;; +1D369;COUNTING ROD TENS DIGIT ONE;No;0;L;;;;10;N;;;;; +1D36A;COUNTING ROD TENS DIGIT TWO;No;0;L;;;;20;N;;;;; +1D36B;COUNTING ROD TENS DIGIT THREE;No;0;L;;;;30;N;;;;; +1D36C;COUNTING ROD TENS DIGIT FOUR;No;0;L;;;;40;N;;;;; +1D36D;COUNTING ROD TENS DIGIT FIVE;No;0;L;;;;50;N;;;;; +1D36E;COUNTING ROD TENS DIGIT SIX;No;0;L;;;;60;N;;;;; +1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;; +1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;; +1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;; +1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4C1;MATHEMATICAL SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D6A4;MATHEMATICAL ITALIC SMALL DOTLESS I;Ll;0;L; 0131;;;;N;;;;; +1D6A5;MATHEMATICAL ITALIC SMALL DOTLESS J;Ll;0;L; 0237;;;;N;;;;; +1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D7CA;MATHEMATICAL BOLD CAPITAL DIGAMMA;Lu;0;L; 03DC;;;;N;;;;; +1D7CB;MATHEMATICAL BOLD SMALL DIGAMMA;Ll;0;L; 03DD;;;;N;;;;; +1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;; +1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;; +1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;; +1F003;MAHJONG TILE NORTH WIND;So;0;ON;;;;;N;;;;; +1F004;MAHJONG TILE RED DRAGON;So;0;ON;;;;;N;;;;; +1F005;MAHJONG TILE GREEN DRAGON;So;0;ON;;;;;N;;;;; +1F006;MAHJONG TILE WHITE DRAGON;So;0;ON;;;;;N;;;;; +1F007;MAHJONG TILE ONE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F008;MAHJONG TILE TWO OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F009;MAHJONG TILE THREE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00A;MAHJONG TILE FOUR OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00B;MAHJONG TILE FIVE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00C;MAHJONG TILE SIX OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00D;MAHJONG TILE SEVEN OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00E;MAHJONG TILE EIGHT OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00F;MAHJONG TILE NINE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F010;MAHJONG TILE ONE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F011;MAHJONG TILE TWO OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F012;MAHJONG TILE THREE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F013;MAHJONG TILE FOUR OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F014;MAHJONG TILE FIVE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F015;MAHJONG TILE SIX OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F016;MAHJONG TILE SEVEN OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F017;MAHJONG TILE EIGHT OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F018;MAHJONG TILE NINE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F019;MAHJONG TILE ONE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01A;MAHJONG TILE TWO OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01B;MAHJONG TILE THREE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01C;MAHJONG TILE FOUR OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01D;MAHJONG TILE FIVE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01E;MAHJONG TILE SIX OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01F;MAHJONG TILE SEVEN OF CIRCLES;So;0;ON;;;;;N;;;;; +1F020;MAHJONG TILE EIGHT OF CIRCLES;So;0;ON;;;;;N;;;;; +1F021;MAHJONG TILE NINE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F022;MAHJONG TILE PLUM;So;0;ON;;;;;N;;;;; +1F023;MAHJONG TILE ORCHID;So;0;ON;;;;;N;;;;; +1F024;MAHJONG TILE BAMBOO;So;0;ON;;;;;N;;;;; +1F025;MAHJONG TILE CHRYSANTHEMUM;So;0;ON;;;;;N;;;;; +1F026;MAHJONG TILE SPRING;So;0;ON;;;;;N;;;;; +1F027;MAHJONG TILE SUMMER;So;0;ON;;;;;N;;;;; +1F028;MAHJONG TILE AUTUMN;So;0;ON;;;;;N;;;;; +1F029;MAHJONG TILE WINTER;So;0;ON;;;;;N;;;;; +1F02A;MAHJONG TILE JOKER;So;0;ON;;;;;N;;;;; +1F02B;MAHJONG TILE BACK;So;0;ON;;;;;N;;;;; +1F030;DOMINO TILE HORIZONTAL BACK;So;0;ON;;;;;N;;;;; +1F031;DOMINO TILE HORIZONTAL-00-00;So;0;ON;;;;;N;;;;; +1F032;DOMINO TILE HORIZONTAL-00-01;So;0;ON;;;;;N;;;;; +1F033;DOMINO TILE HORIZONTAL-00-02;So;0;ON;;;;;N;;;;; +1F034;DOMINO TILE HORIZONTAL-00-03;So;0;ON;;;;;N;;;;; +1F035;DOMINO TILE HORIZONTAL-00-04;So;0;ON;;;;;N;;;;; +1F036;DOMINO TILE HORIZONTAL-00-05;So;0;ON;;;;;N;;;;; +1F037;DOMINO TILE HORIZONTAL-00-06;So;0;ON;;;;;N;;;;; +1F038;DOMINO TILE HORIZONTAL-01-00;So;0;ON;;;;;N;;;;; +1F039;DOMINO TILE HORIZONTAL-01-01;So;0;ON;;;;;N;;;;; +1F03A;DOMINO TILE HORIZONTAL-01-02;So;0;ON;;;;;N;;;;; +1F03B;DOMINO TILE HORIZONTAL-01-03;So;0;ON;;;;;N;;;;; +1F03C;DOMINO TILE HORIZONTAL-01-04;So;0;ON;;;;;N;;;;; +1F03D;DOMINO TILE HORIZONTAL-01-05;So;0;ON;;;;;N;;;;; +1F03E;DOMINO TILE HORIZONTAL-01-06;So;0;ON;;;;;N;;;;; +1F03F;DOMINO TILE HORIZONTAL-02-00;So;0;ON;;;;;N;;;;; +1F040;DOMINO TILE HORIZONTAL-02-01;So;0;ON;;;;;N;;;;; +1F041;DOMINO TILE HORIZONTAL-02-02;So;0;ON;;;;;N;;;;; +1F042;DOMINO TILE HORIZONTAL-02-03;So;0;ON;;;;;N;;;;; +1F043;DOMINO TILE HORIZONTAL-02-04;So;0;ON;;;;;N;;;;; +1F044;DOMINO TILE HORIZONTAL-02-05;So;0;ON;;;;;N;;;;; +1F045;DOMINO TILE HORIZONTAL-02-06;So;0;ON;;;;;N;;;;; +1F046;DOMINO TILE HORIZONTAL-03-00;So;0;ON;;;;;N;;;;; +1F047;DOMINO TILE HORIZONTAL-03-01;So;0;ON;;;;;N;;;;; +1F048;DOMINO TILE HORIZONTAL-03-02;So;0;ON;;;;;N;;;;; +1F049;DOMINO TILE HORIZONTAL-03-03;So;0;ON;;;;;N;;;;; +1F04A;DOMINO TILE HORIZONTAL-03-04;So;0;ON;;;;;N;;;;; +1F04B;DOMINO TILE HORIZONTAL-03-05;So;0;ON;;;;;N;;;;; +1F04C;DOMINO TILE HORIZONTAL-03-06;So;0;ON;;;;;N;;;;; +1F04D;DOMINO TILE HORIZONTAL-04-00;So;0;ON;;;;;N;;;;; +1F04E;DOMINO TILE HORIZONTAL-04-01;So;0;ON;;;;;N;;;;; +1F04F;DOMINO TILE HORIZONTAL-04-02;So;0;ON;;;;;N;;;;; +1F050;DOMINO TILE HORIZONTAL-04-03;So;0;ON;;;;;N;;;;; +1F051;DOMINO TILE HORIZONTAL-04-04;So;0;ON;;;;;N;;;;; +1F052;DOMINO TILE HORIZONTAL-04-05;So;0;ON;;;;;N;;;;; +1F053;DOMINO TILE HORIZONTAL-04-06;So;0;ON;;;;;N;;;;; +1F054;DOMINO TILE HORIZONTAL-05-00;So;0;ON;;;;;N;;;;; +1F055;DOMINO TILE HORIZONTAL-05-01;So;0;ON;;;;;N;;;;; +1F056;DOMINO TILE HORIZONTAL-05-02;So;0;ON;;;;;N;;;;; +1F057;DOMINO TILE HORIZONTAL-05-03;So;0;ON;;;;;N;;;;; +1F058;DOMINO TILE HORIZONTAL-05-04;So;0;ON;;;;;N;;;;; +1F059;DOMINO TILE HORIZONTAL-05-05;So;0;ON;;;;;N;;;;; +1F05A;DOMINO TILE HORIZONTAL-05-06;So;0;ON;;;;;N;;;;; +1F05B;DOMINO TILE HORIZONTAL-06-00;So;0;ON;;;;;N;;;;; +1F05C;DOMINO TILE HORIZONTAL-06-01;So;0;ON;;;;;N;;;;; +1F05D;DOMINO TILE HORIZONTAL-06-02;So;0;ON;;;;;N;;;;; +1F05E;DOMINO TILE HORIZONTAL-06-03;So;0;ON;;;;;N;;;;; +1F05F;DOMINO TILE HORIZONTAL-06-04;So;0;ON;;;;;N;;;;; +1F060;DOMINO TILE HORIZONTAL-06-05;So;0;ON;;;;;N;;;;; +1F061;DOMINO TILE HORIZONTAL-06-06;So;0;ON;;;;;N;;;;; +1F062;DOMINO TILE VERTICAL BACK;So;0;ON;;;;;N;;;;; +1F063;DOMINO TILE VERTICAL-00-00;So;0;ON;;;;;N;;;;; +1F064;DOMINO TILE VERTICAL-00-01;So;0;ON;;;;;N;;;;; +1F065;DOMINO TILE VERTICAL-00-02;So;0;ON;;;;;N;;;;; +1F066;DOMINO TILE VERTICAL-00-03;So;0;ON;;;;;N;;;;; +1F067;DOMINO TILE VERTICAL-00-04;So;0;ON;;;;;N;;;;; +1F068;DOMINO TILE VERTICAL-00-05;So;0;ON;;;;;N;;;;; +1F069;DOMINO TILE VERTICAL-00-06;So;0;ON;;;;;N;;;;; +1F06A;DOMINO TILE VERTICAL-01-00;So;0;ON;;;;;N;;;;; +1F06B;DOMINO TILE VERTICAL-01-01;So;0;ON;;;;;N;;;;; +1F06C;DOMINO TILE VERTICAL-01-02;So;0;ON;;;;;N;;;;; +1F06D;DOMINO TILE VERTICAL-01-03;So;0;ON;;;;;N;;;;; +1F06E;DOMINO TILE VERTICAL-01-04;So;0;ON;;;;;N;;;;; +1F06F;DOMINO TILE VERTICAL-01-05;So;0;ON;;;;;N;;;;; +1F070;DOMINO TILE VERTICAL-01-06;So;0;ON;;;;;N;;;;; +1F071;DOMINO TILE VERTICAL-02-00;So;0;ON;;;;;N;;;;; +1F072;DOMINO TILE VERTICAL-02-01;So;0;ON;;;;;N;;;;; +1F073;DOMINO TILE VERTICAL-02-02;So;0;ON;;;;;N;;;;; +1F074;DOMINO TILE VERTICAL-02-03;So;0;ON;;;;;N;;;;; +1F075;DOMINO TILE VERTICAL-02-04;So;0;ON;;;;;N;;;;; +1F076;DOMINO TILE VERTICAL-02-05;So;0;ON;;;;;N;;;;; +1F077;DOMINO TILE VERTICAL-02-06;So;0;ON;;;;;N;;;;; +1F078;DOMINO TILE VERTICAL-03-00;So;0;ON;;;;;N;;;;; +1F079;DOMINO TILE VERTICAL-03-01;So;0;ON;;;;;N;;;;; +1F07A;DOMINO TILE VERTICAL-03-02;So;0;ON;;;;;N;;;;; +1F07B;DOMINO TILE VERTICAL-03-03;So;0;ON;;;;;N;;;;; +1F07C;DOMINO TILE VERTICAL-03-04;So;0;ON;;;;;N;;;;; +1F07D;DOMINO TILE VERTICAL-03-05;So;0;ON;;;;;N;;;;; +1F07E;DOMINO TILE VERTICAL-03-06;So;0;ON;;;;;N;;;;; +1F07F;DOMINO TILE VERTICAL-04-00;So;0;ON;;;;;N;;;;; +1F080;DOMINO TILE VERTICAL-04-01;So;0;ON;;;;;N;;;;; +1F081;DOMINO TILE VERTICAL-04-02;So;0;ON;;;;;N;;;;; +1F082;DOMINO TILE VERTICAL-04-03;So;0;ON;;;;;N;;;;; +1F083;DOMINO TILE VERTICAL-04-04;So;0;ON;;;;;N;;;;; +1F084;DOMINO TILE VERTICAL-04-05;So;0;ON;;;;;N;;;;; +1F085;DOMINO TILE VERTICAL-04-06;So;0;ON;;;;;N;;;;; +1F086;DOMINO TILE VERTICAL-05-00;So;0;ON;;;;;N;;;;; +1F087;DOMINO TILE VERTICAL-05-01;So;0;ON;;;;;N;;;;; +1F088;DOMINO TILE VERTICAL-05-02;So;0;ON;;;;;N;;;;; +1F089;DOMINO TILE VERTICAL-05-03;So;0;ON;;;;;N;;;;; +1F08A;DOMINO TILE VERTICAL-05-04;So;0;ON;;;;;N;;;;; +1F08B;DOMINO TILE VERTICAL-05-05;So;0;ON;;;;;N;;;;; +1F08C;DOMINO TILE VERTICAL-05-06;So;0;ON;;;;;N;;;;; +1F08D;DOMINO TILE VERTICAL-06-00;So;0;ON;;;;;N;;;;; +1F08E;DOMINO TILE VERTICAL-06-01;So;0;ON;;;;;N;;;;; +1F08F;DOMINO TILE VERTICAL-06-02;So;0;ON;;;;;N;;;;; +1F090;DOMINO TILE VERTICAL-06-03;So;0;ON;;;;;N;;;;; +1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;; +1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;; +1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;; +20000;;Lo;0;L;;;;;N;;;;; +2A6D6;;Lo;0;L;;;;;N;;;;; +2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;; +2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;; +2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;; +2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;; +2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;; +2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;; +2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;; +2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;; +2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;; +2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;; +2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;; +2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;; +2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;; +2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;; +2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;; +2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;; +2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;; +2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;; +2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;; +2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;; +2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;; +2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;; +2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;; +2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;; +2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;; +2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;; +2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;; +2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;; +2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;; +2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;; +2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;; +2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;; +2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;; +2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;; +2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;; +2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;; +2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;; +2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;; +2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;; +2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;; +2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;; +2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;; +2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;; +2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;; +2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;; +2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;; +2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;; +2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;; +2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;; +2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;; +2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;; +2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;; +2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;; +2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;; +2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;; +2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;; +2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;; +2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;; +2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;; +2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;; +2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;; +2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;; +2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;; +2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;; +2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;; +2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;; +2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;; +2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;; +2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;; +2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;; +2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;; +2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;; +2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;; +2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;; +2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;; +2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;; +2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;; +2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;; +2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;; +2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;; +2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;; +2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;; +2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;; +2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;; +2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;; +2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;; +2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;; +2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;; +2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;; +2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;; +2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;; +2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;; +2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;; +2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;; +2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;; +2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;; +2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;; +2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;; +2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;; +2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;; +2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;; +2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;; +2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;; +2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;; +2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;36FC;;;;N;;;;; +2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;; +2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;; +2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;; +2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;; +2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;; +2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;; +2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;; +2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;; +2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;; +2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;; +2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;; +2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F53;;;;N;;;;; +2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;; +2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;; +2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;; +2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;; +2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;; +2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;; +2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;; +2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;; +2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;; +2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;; +2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;; +2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;; +2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;; +2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;; +2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;; +2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;; +2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;; +2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;; +2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;; +2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;; +2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;; +2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;; +2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;; +2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;; +2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;; +2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;; +2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;; +2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;9;N;;;;; +2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;; +2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;; +2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;; +2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;; +2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;; +2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;; +2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;; +2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;; +2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;; +2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;; +2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;; +2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;; +2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;; +2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;; +2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;; +2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;; +2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;; +2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;; +2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;; +2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;; +2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;; +2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;; +2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;; +2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;; +2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;; +2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;; +2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;; +2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;; +2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;; +2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;; +2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;; +2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;; +2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;; +2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;; +2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;; +2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;; +2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;; +2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;; +2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;; +2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;; +2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;; +2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;; +2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;; +2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;; +2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;; +2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;; +2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;; +2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;; +2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;; +2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;; +2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;; +2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;; +2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;; +2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;; +2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;; +2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;; +2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;; +2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;; +2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;; +2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;; +2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;; +2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;; +2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;; +2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;; +2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;; +2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;; +2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;; +2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;; +2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;; +2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;; +2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;; +2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;; +2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;; +2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;; +2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;; +2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;; +2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;; +2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;; +2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;; +2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;; +2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;; +2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;; +2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;; +2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;; +2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;; +2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;; +2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;; +2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;; +2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;; +2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;; +2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;; +2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;; +2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;; +2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;; +2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;; +2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;; +2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;; +2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;; +2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;; +2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;; +2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;; +2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;; +2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;; +2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;; +2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;; +2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;; +2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;; +2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;; +2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;; +2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;; +2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;; +2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;; +2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;; +2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;; +2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;; +2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;; +2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;; +2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;; +2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;; +2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;; +2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;; +2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;; +2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;; +2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;; +2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;; +2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;; +2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;; +2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;; +2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;; +2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;; +2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;; +2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;; +2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;; +2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;; +2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;; +2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;; +2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;; +2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;; +2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;; +2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;; +2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;; +2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;; +2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;243AB;;;;N;;;;; +2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;; +2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;; +2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;; +2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;; +2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;; +2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;; +2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;; +2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;; +2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;; +2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;; +2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;; +2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;; +2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;; +2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;; +2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;; +2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;; +2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;; +2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;; +2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;; +2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;; +2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;; +2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;; +2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;; +2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;; +2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;; +2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;; +2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;; +2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;; +2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;; +2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;; +2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;; +2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;; +2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;; +2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;; +2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;; +2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;; +2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;; +2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;; +2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;; +2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;; +2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;; +2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;; +2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;; +2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;; +2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;; +2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;; +2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;; +2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;; +2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;; +2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;; +2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;; +2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;; +2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;; +2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;; +2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;; +2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;; +2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;; +2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;; +2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;; +2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;; +2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;; +2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;; +2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;; +2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AEE;;;;N;;;;; +2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;; +2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;; +2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;; +2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;; +2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;; +2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;; +2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;; +2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;; +2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;; +2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;; +2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;; +2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;; +2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;; +2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;; +2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;; +2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;; +2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;; +2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;; +2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;; +2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;; +2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;; +2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;; +2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;; +2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;; +2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;; +2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;; +2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;; +2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;; +2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;; +2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;; +2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;; +2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;; +2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;; +2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;; +2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;; +2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;; +2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;; +2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;; +2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;; +2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;; +2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;; +2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;; +2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;; +2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;; +2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;; +2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;; +2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;; +2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;; +2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;; +2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;; +2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;; +2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;; +2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;; +2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;; +2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;; +2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;; +2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;; +2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;; +2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;; +2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;; +2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;; +2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;; +2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;; +2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;; +2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;; +2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;; +2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;; +2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;; +2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;; +2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;; +2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;; +2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;; +2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;; +2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;; +2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;; +2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;; +2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;; +2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;; +2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;; +2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;; +2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;; +2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;; +2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;; +2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;; +2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;; +2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;; +2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;; +2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;; +2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;; +2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;; +2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;; +2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;; +2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;; +2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;; +2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;; +2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;45D7;;;;N;;;;; +2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;; +2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;; +2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;; +2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;; +2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;; +2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;; +2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;; +2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;; +2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;; +2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;; +2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;; +2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;; +2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;; +2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;; +2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;; +2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;; +2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;; +2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;; +2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;; +2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;; +2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;; +2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;; +2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;; +2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;; +2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;; +2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;; +2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;; +2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;; +2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;; +2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;; +2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;; +2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;; +2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;; +2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;; +2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;; +2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;; +2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;; +2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;; +2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;; +2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;; +2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;; +2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;; +2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;; +2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;; +2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;; +2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;; +2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;; +2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;; +2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;; +2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;; +2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;; +2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;; +2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;; +2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;; +2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;; +2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;; +2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;; +2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;; +2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;; +2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;; +2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;; +2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;; +2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;; +2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;; +2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;; +2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;; +2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;; +2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;; +2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;; +2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;; +2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;; +2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;; +2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;; +2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;; +2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;; +2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;; +2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;; +2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;; +2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;; +2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;; +2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;; +2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;; +2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;; +2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;; +2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;; +2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;; +2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;; +2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;; +2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;; +2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;; +2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;; +2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;; +2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;; +2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;; +E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;; +E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; +E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;; +E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;; +E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;; +E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;; +E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;; +E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;; +E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;; +E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;; +E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;; +E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;; +E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;; +E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;; +E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;; +E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;; +E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;; +E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;; +E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;; +E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;; +E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;; +E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;; +E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;; +E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;; +E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;; +E003A;TAG COLON;Cf;0;BN;;;;;N;;;;; +E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;; +E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;; +E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;; +E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;; +E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;; +E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;; +E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;; +E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;; +E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;; +E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;; +E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;; +E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;; +E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;; +E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;; +E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;; +E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;; +E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;; +E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;; +E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;; +E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;; +E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;; +E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;; +E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;; +E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;; +E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;; +E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;; +E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;; +E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;; +E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;; +E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;; +E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;; +E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;; +E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;; +E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;; +E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;; +E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;; +E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;; +E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;; +E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;; +E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;; +E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;; +E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;; +E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;; +E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;; +E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;; +E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;; +E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;; +E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;; +E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;; +E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;; +E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;; +E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;; +E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;; +E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;; +E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;; +E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;; +E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;; +E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;; +E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;; +E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;; +E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;; +E0100;VARIATION SELECTOR-17;Mn;0;NSM;;;;;N;;;;; +E0101;VARIATION SELECTOR-18;Mn;0;NSM;;;;;N;;;;; +E0102;VARIATION SELECTOR-19;Mn;0;NSM;;;;;N;;;;; +E0103;VARIATION SELECTOR-20;Mn;0;NSM;;;;;N;;;;; +E0104;VARIATION SELECTOR-21;Mn;0;NSM;;;;;N;;;;; +E0105;VARIATION SELECTOR-22;Mn;0;NSM;;;;;N;;;;; +E0106;VARIATION SELECTOR-23;Mn;0;NSM;;;;;N;;;;; +E0107;VARIATION SELECTOR-24;Mn;0;NSM;;;;;N;;;;; +E0108;VARIATION SELECTOR-25;Mn;0;NSM;;;;;N;;;;; +E0109;VARIATION SELECTOR-26;Mn;0;NSM;;;;;N;;;;; +E010A;VARIATION SELECTOR-27;Mn;0;NSM;;;;;N;;;;; +E010B;VARIATION SELECTOR-28;Mn;0;NSM;;;;;N;;;;; +E010C;VARIATION SELECTOR-29;Mn;0;NSM;;;;;N;;;;; +E010D;VARIATION SELECTOR-30;Mn;0;NSM;;;;;N;;;;; +E010E;VARIATION SELECTOR-31;Mn;0;NSM;;;;;N;;;;; +E010F;VARIATION SELECTOR-32;Mn;0;NSM;;;;;N;;;;; +E0110;VARIATION SELECTOR-33;Mn;0;NSM;;;;;N;;;;; +E0111;VARIATION SELECTOR-34;Mn;0;NSM;;;;;N;;;;; +E0112;VARIATION SELECTOR-35;Mn;0;NSM;;;;;N;;;;; +E0113;VARIATION SELECTOR-36;Mn;0;NSM;;;;;N;;;;; +E0114;VARIATION SELECTOR-37;Mn;0;NSM;;;;;N;;;;; +E0115;VARIATION SELECTOR-38;Mn;0;NSM;;;;;N;;;;; +E0116;VARIATION SELECTOR-39;Mn;0;NSM;;;;;N;;;;; +E0117;VARIATION SELECTOR-40;Mn;0;NSM;;;;;N;;;;; +E0118;VARIATION SELECTOR-41;Mn;0;NSM;;;;;N;;;;; +E0119;VARIATION SELECTOR-42;Mn;0;NSM;;;;;N;;;;; +E011A;VARIATION SELECTOR-43;Mn;0;NSM;;;;;N;;;;; +E011B;VARIATION SELECTOR-44;Mn;0;NSM;;;;;N;;;;; +E011C;VARIATION SELECTOR-45;Mn;0;NSM;;;;;N;;;;; +E011D;VARIATION SELECTOR-46;Mn;0;NSM;;;;;N;;;;; +E011E;VARIATION SELECTOR-47;Mn;0;NSM;;;;;N;;;;; +E011F;VARIATION SELECTOR-48;Mn;0;NSM;;;;;N;;;;; +E0120;VARIATION SELECTOR-49;Mn;0;NSM;;;;;N;;;;; +E0121;VARIATION SELECTOR-50;Mn;0;NSM;;;;;N;;;;; +E0122;VARIATION SELECTOR-51;Mn;0;NSM;;;;;N;;;;; +E0123;VARIATION SELECTOR-52;Mn;0;NSM;;;;;N;;;;; +E0124;VARIATION SELECTOR-53;Mn;0;NSM;;;;;N;;;;; +E0125;VARIATION SELECTOR-54;Mn;0;NSM;;;;;N;;;;; +E0126;VARIATION SELECTOR-55;Mn;0;NSM;;;;;N;;;;; +E0127;VARIATION SELECTOR-56;Mn;0;NSM;;;;;N;;;;; +E0128;VARIATION SELECTOR-57;Mn;0;NSM;;;;;N;;;;; +E0129;VARIATION SELECTOR-58;Mn;0;NSM;;;;;N;;;;; +E012A;VARIATION SELECTOR-59;Mn;0;NSM;;;;;N;;;;; +E012B;VARIATION SELECTOR-60;Mn;0;NSM;;;;;N;;;;; +E012C;VARIATION SELECTOR-61;Mn;0;NSM;;;;;N;;;;; +E012D;VARIATION SELECTOR-62;Mn;0;NSM;;;;;N;;;;; +E012E;VARIATION SELECTOR-63;Mn;0;NSM;;;;;N;;;;; +E012F;VARIATION SELECTOR-64;Mn;0;NSM;;;;;N;;;;; +E0130;VARIATION SELECTOR-65;Mn;0;NSM;;;;;N;;;;; +E0131;VARIATION SELECTOR-66;Mn;0;NSM;;;;;N;;;;; +E0132;VARIATION SELECTOR-67;Mn;0;NSM;;;;;N;;;;; +E0133;VARIATION SELECTOR-68;Mn;0;NSM;;;;;N;;;;; +E0134;VARIATION SELECTOR-69;Mn;0;NSM;;;;;N;;;;; +E0135;VARIATION SELECTOR-70;Mn;0;NSM;;;;;N;;;;; +E0136;VARIATION SELECTOR-71;Mn;0;NSM;;;;;N;;;;; +E0137;VARIATION SELECTOR-72;Mn;0;NSM;;;;;N;;;;; +E0138;VARIATION SELECTOR-73;Mn;0;NSM;;;;;N;;;;; +E0139;VARIATION SELECTOR-74;Mn;0;NSM;;;;;N;;;;; +E013A;VARIATION SELECTOR-75;Mn;0;NSM;;;;;N;;;;; +E013B;VARIATION SELECTOR-76;Mn;0;NSM;;;;;N;;;;; +E013C;VARIATION SELECTOR-77;Mn;0;NSM;;;;;N;;;;; +E013D;VARIATION SELECTOR-78;Mn;0;NSM;;;;;N;;;;; +E013E;VARIATION SELECTOR-79;Mn;0;NSM;;;;;N;;;;; +E013F;VARIATION SELECTOR-80;Mn;0;NSM;;;;;N;;;;; +E0140;VARIATION SELECTOR-81;Mn;0;NSM;;;;;N;;;;; +E0141;VARIATION SELECTOR-82;Mn;0;NSM;;;;;N;;;;; +E0142;VARIATION SELECTOR-83;Mn;0;NSM;;;;;N;;;;; +E0143;VARIATION SELECTOR-84;Mn;0;NSM;;;;;N;;;;; +E0144;VARIATION SELECTOR-85;Mn;0;NSM;;;;;N;;;;; +E0145;VARIATION SELECTOR-86;Mn;0;NSM;;;;;N;;;;; +E0146;VARIATION SELECTOR-87;Mn;0;NSM;;;;;N;;;;; +E0147;VARIATION SELECTOR-88;Mn;0;NSM;;;;;N;;;;; +E0148;VARIATION SELECTOR-89;Mn;0;NSM;;;;;N;;;;; +E0149;VARIATION SELECTOR-90;Mn;0;NSM;;;;;N;;;;; +E014A;VARIATION SELECTOR-91;Mn;0;NSM;;;;;N;;;;; +E014B;VARIATION SELECTOR-92;Mn;0;NSM;;;;;N;;;;; +E014C;VARIATION SELECTOR-93;Mn;0;NSM;;;;;N;;;;; +E014D;VARIATION SELECTOR-94;Mn;0;NSM;;;;;N;;;;; +E014E;VARIATION SELECTOR-95;Mn;0;NSM;;;;;N;;;;; +E014F;VARIATION SELECTOR-96;Mn;0;NSM;;;;;N;;;;; +E0150;VARIATION SELECTOR-97;Mn;0;NSM;;;;;N;;;;; +E0151;VARIATION SELECTOR-98;Mn;0;NSM;;;;;N;;;;; +E0152;VARIATION SELECTOR-99;Mn;0;NSM;;;;;N;;;;; +E0153;VARIATION SELECTOR-100;Mn;0;NSM;;;;;N;;;;; +E0154;VARIATION SELECTOR-101;Mn;0;NSM;;;;;N;;;;; +E0155;VARIATION SELECTOR-102;Mn;0;NSM;;;;;N;;;;; +E0156;VARIATION SELECTOR-103;Mn;0;NSM;;;;;N;;;;; +E0157;VARIATION SELECTOR-104;Mn;0;NSM;;;;;N;;;;; +E0158;VARIATION SELECTOR-105;Mn;0;NSM;;;;;N;;;;; +E0159;VARIATION SELECTOR-106;Mn;0;NSM;;;;;N;;;;; +E015A;VARIATION SELECTOR-107;Mn;0;NSM;;;;;N;;;;; +E015B;VARIATION SELECTOR-108;Mn;0;NSM;;;;;N;;;;; +E015C;VARIATION SELECTOR-109;Mn;0;NSM;;;;;N;;;;; +E015D;VARIATION SELECTOR-110;Mn;0;NSM;;;;;N;;;;; +E015E;VARIATION SELECTOR-111;Mn;0;NSM;;;;;N;;;;; +E015F;VARIATION SELECTOR-112;Mn;0;NSM;;;;;N;;;;; +E0160;VARIATION SELECTOR-113;Mn;0;NSM;;;;;N;;;;; +E0161;VARIATION SELECTOR-114;Mn;0;NSM;;;;;N;;;;; +E0162;VARIATION SELECTOR-115;Mn;0;NSM;;;;;N;;;;; +E0163;VARIATION SELECTOR-116;Mn;0;NSM;;;;;N;;;;; +E0164;VARIATION SELECTOR-117;Mn;0;NSM;;;;;N;;;;; +E0165;VARIATION SELECTOR-118;Mn;0;NSM;;;;;N;;;;; +E0166;VARIATION SELECTOR-119;Mn;0;NSM;;;;;N;;;;; +E0167;VARIATION SELECTOR-120;Mn;0;NSM;;;;;N;;;;; +E0168;VARIATION SELECTOR-121;Mn;0;NSM;;;;;N;;;;; +E0169;VARIATION SELECTOR-122;Mn;0;NSM;;;;;N;;;;; +E016A;VARIATION SELECTOR-123;Mn;0;NSM;;;;;N;;;;; +E016B;VARIATION SELECTOR-124;Mn;0;NSM;;;;;N;;;;; +E016C;VARIATION SELECTOR-125;Mn;0;NSM;;;;;N;;;;; +E016D;VARIATION SELECTOR-126;Mn;0;NSM;;;;;N;;;;; +E016E;VARIATION SELECTOR-127;Mn;0;NSM;;;;;N;;;;; +E016F;VARIATION SELECTOR-128;Mn;0;NSM;;;;;N;;;;; +E0170;VARIATION SELECTOR-129;Mn;0;NSM;;;;;N;;;;; +E0171;VARIATION SELECTOR-130;Mn;0;NSM;;;;;N;;;;; +E0172;VARIATION SELECTOR-131;Mn;0;NSM;;;;;N;;;;; +E0173;VARIATION SELECTOR-132;Mn;0;NSM;;;;;N;;;;; +E0174;VARIATION SELECTOR-133;Mn;0;NSM;;;;;N;;;;; +E0175;VARIATION SELECTOR-134;Mn;0;NSM;;;;;N;;;;; +E0176;VARIATION SELECTOR-135;Mn;0;NSM;;;;;N;;;;; +E0177;VARIATION SELECTOR-136;Mn;0;NSM;;;;;N;;;;; +E0178;VARIATION SELECTOR-137;Mn;0;NSM;;;;;N;;;;; +E0179;VARIATION SELECTOR-138;Mn;0;NSM;;;;;N;;;;; +E017A;VARIATION SELECTOR-139;Mn;0;NSM;;;;;N;;;;; +E017B;VARIATION SELECTOR-140;Mn;0;NSM;;;;;N;;;;; +E017C;VARIATION SELECTOR-141;Mn;0;NSM;;;;;N;;;;; +E017D;VARIATION SELECTOR-142;Mn;0;NSM;;;;;N;;;;; +E017E;VARIATION SELECTOR-143;Mn;0;NSM;;;;;N;;;;; +E017F;VARIATION SELECTOR-144;Mn;0;NSM;;;;;N;;;;; +E0180;VARIATION SELECTOR-145;Mn;0;NSM;;;;;N;;;;; +E0181;VARIATION SELECTOR-146;Mn;0;NSM;;;;;N;;;;; +E0182;VARIATION SELECTOR-147;Mn;0;NSM;;;;;N;;;;; +E0183;VARIATION SELECTOR-148;Mn;0;NSM;;;;;N;;;;; +E0184;VARIATION SELECTOR-149;Mn;0;NSM;;;;;N;;;;; +E0185;VARIATION SELECTOR-150;Mn;0;NSM;;;;;N;;;;; +E0186;VARIATION SELECTOR-151;Mn;0;NSM;;;;;N;;;;; +E0187;VARIATION SELECTOR-152;Mn;0;NSM;;;;;N;;;;; +E0188;VARIATION SELECTOR-153;Mn;0;NSM;;;;;N;;;;; +E0189;VARIATION SELECTOR-154;Mn;0;NSM;;;;;N;;;;; +E018A;VARIATION SELECTOR-155;Mn;0;NSM;;;;;N;;;;; +E018B;VARIATION SELECTOR-156;Mn;0;NSM;;;;;N;;;;; +E018C;VARIATION SELECTOR-157;Mn;0;NSM;;;;;N;;;;; +E018D;VARIATION SELECTOR-158;Mn;0;NSM;;;;;N;;;;; +E018E;VARIATION SELECTOR-159;Mn;0;NSM;;;;;N;;;;; +E018F;VARIATION SELECTOR-160;Mn;0;NSM;;;;;N;;;;; +E0190;VARIATION SELECTOR-161;Mn;0;NSM;;;;;N;;;;; +E0191;VARIATION SELECTOR-162;Mn;0;NSM;;;;;N;;;;; +E0192;VARIATION SELECTOR-163;Mn;0;NSM;;;;;N;;;;; +E0193;VARIATION SELECTOR-164;Mn;0;NSM;;;;;N;;;;; +E0194;VARIATION SELECTOR-165;Mn;0;NSM;;;;;N;;;;; +E0195;VARIATION SELECTOR-166;Mn;0;NSM;;;;;N;;;;; +E0196;VARIATION SELECTOR-167;Mn;0;NSM;;;;;N;;;;; +E0197;VARIATION SELECTOR-168;Mn;0;NSM;;;;;N;;;;; +E0198;VARIATION SELECTOR-169;Mn;0;NSM;;;;;N;;;;; +E0199;VARIATION SELECTOR-170;Mn;0;NSM;;;;;N;;;;; +E019A;VARIATION SELECTOR-171;Mn;0;NSM;;;;;N;;;;; +E019B;VARIATION SELECTOR-172;Mn;0;NSM;;;;;N;;;;; +E019C;VARIATION SELECTOR-173;Mn;0;NSM;;;;;N;;;;; +E019D;VARIATION SELECTOR-174;Mn;0;NSM;;;;;N;;;;; +E019E;VARIATION SELECTOR-175;Mn;0;NSM;;;;;N;;;;; +E019F;VARIATION SELECTOR-176;Mn;0;NSM;;;;;N;;;;; +E01A0;VARIATION SELECTOR-177;Mn;0;NSM;;;;;N;;;;; +E01A1;VARIATION SELECTOR-178;Mn;0;NSM;;;;;N;;;;; +E01A2;VARIATION SELECTOR-179;Mn;0;NSM;;;;;N;;;;; +E01A3;VARIATION SELECTOR-180;Mn;0;NSM;;;;;N;;;;; +E01A4;VARIATION SELECTOR-181;Mn;0;NSM;;;;;N;;;;; +E01A5;VARIATION SELECTOR-182;Mn;0;NSM;;;;;N;;;;; +E01A6;VARIATION SELECTOR-183;Mn;0;NSM;;;;;N;;;;; +E01A7;VARIATION SELECTOR-184;Mn;0;NSM;;;;;N;;;;; +E01A8;VARIATION SELECTOR-185;Mn;0;NSM;;;;;N;;;;; +E01A9;VARIATION SELECTOR-186;Mn;0;NSM;;;;;N;;;;; +E01AA;VARIATION SELECTOR-187;Mn;0;NSM;;;;;N;;;;; +E01AB;VARIATION SELECTOR-188;Mn;0;NSM;;;;;N;;;;; +E01AC;VARIATION SELECTOR-189;Mn;0;NSM;;;;;N;;;;; +E01AD;VARIATION SELECTOR-190;Mn;0;NSM;;;;;N;;;;; +E01AE;VARIATION SELECTOR-191;Mn;0;NSM;;;;;N;;;;; +E01AF;VARIATION SELECTOR-192;Mn;0;NSM;;;;;N;;;;; +E01B0;VARIATION SELECTOR-193;Mn;0;NSM;;;;;N;;;;; +E01B1;VARIATION SELECTOR-194;Mn;0;NSM;;;;;N;;;;; +E01B2;VARIATION SELECTOR-195;Mn;0;NSM;;;;;N;;;;; +E01B3;VARIATION SELECTOR-196;Mn;0;NSM;;;;;N;;;;; +E01B4;VARIATION SELECTOR-197;Mn;0;NSM;;;;;N;;;;; +E01B5;VARIATION SELECTOR-198;Mn;0;NSM;;;;;N;;;;; +E01B6;VARIATION SELECTOR-199;Mn;0;NSM;;;;;N;;;;; +E01B7;VARIATION SELECTOR-200;Mn;0;NSM;;;;;N;;;;; +E01B8;VARIATION SELECTOR-201;Mn;0;NSM;;;;;N;;;;; +E01B9;VARIATION SELECTOR-202;Mn;0;NSM;;;;;N;;;;; +E01BA;VARIATION SELECTOR-203;Mn;0;NSM;;;;;N;;;;; +E01BB;VARIATION SELECTOR-204;Mn;0;NSM;;;;;N;;;;; +E01BC;VARIATION SELECTOR-205;Mn;0;NSM;;;;;N;;;;; +E01BD;VARIATION SELECTOR-206;Mn;0;NSM;;;;;N;;;;; +E01BE;VARIATION SELECTOR-207;Mn;0;NSM;;;;;N;;;;; +E01BF;VARIATION SELECTOR-208;Mn;0;NSM;;;;;N;;;;; +E01C0;VARIATION SELECTOR-209;Mn;0;NSM;;;;;N;;;;; +E01C1;VARIATION SELECTOR-210;Mn;0;NSM;;;;;N;;;;; +E01C2;VARIATION SELECTOR-211;Mn;0;NSM;;;;;N;;;;; +E01C3;VARIATION SELECTOR-212;Mn;0;NSM;;;;;N;;;;; +E01C4;VARIATION SELECTOR-213;Mn;0;NSM;;;;;N;;;;; +E01C5;VARIATION SELECTOR-214;Mn;0;NSM;;;;;N;;;;; +E01C6;VARIATION SELECTOR-215;Mn;0;NSM;;;;;N;;;;; +E01C7;VARIATION SELECTOR-216;Mn;0;NSM;;;;;N;;;;; +E01C8;VARIATION SELECTOR-217;Mn;0;NSM;;;;;N;;;;; +E01C9;VARIATION SELECTOR-218;Mn;0;NSM;;;;;N;;;;; +E01CA;VARIATION SELECTOR-219;Mn;0;NSM;;;;;N;;;;; +E01CB;VARIATION SELECTOR-220;Mn;0;NSM;;;;;N;;;;; +E01CC;VARIATION SELECTOR-221;Mn;0;NSM;;;;;N;;;;; +E01CD;VARIATION SELECTOR-222;Mn;0;NSM;;;;;N;;;;; +E01CE;VARIATION SELECTOR-223;Mn;0;NSM;;;;;N;;;;; +E01CF;VARIATION SELECTOR-224;Mn;0;NSM;;;;;N;;;;; +E01D0;VARIATION SELECTOR-225;Mn;0;NSM;;;;;N;;;;; +E01D1;VARIATION SELECTOR-226;Mn;0;NSM;;;;;N;;;;; +E01D2;VARIATION SELECTOR-227;Mn;0;NSM;;;;;N;;;;; +E01D3;VARIATION SELECTOR-228;Mn;0;NSM;;;;;N;;;;; +E01D4;VARIATION SELECTOR-229;Mn;0;NSM;;;;;N;;;;; +E01D5;VARIATION SELECTOR-230;Mn;0;NSM;;;;;N;;;;; +E01D6;VARIATION SELECTOR-231;Mn;0;NSM;;;;;N;;;;; +E01D7;VARIATION SELECTOR-232;Mn;0;NSM;;;;;N;;;;; +E01D8;VARIATION SELECTOR-233;Mn;0;NSM;;;;;N;;;;; +E01D9;VARIATION SELECTOR-234;Mn;0;NSM;;;;;N;;;;; +E01DA;VARIATION SELECTOR-235;Mn;0;NSM;;;;;N;;;;; +E01DB;VARIATION SELECTOR-236;Mn;0;NSM;;;;;N;;;;; +E01DC;VARIATION SELECTOR-237;Mn;0;NSM;;;;;N;;;;; +E01DD;VARIATION SELECTOR-238;Mn;0;NSM;;;;;N;;;;; +E01DE;VARIATION SELECTOR-239;Mn;0;NSM;;;;;N;;;;; +E01DF;VARIATION SELECTOR-240;Mn;0;NSM;;;;;N;;;;; +E01E0;VARIATION SELECTOR-241;Mn;0;NSM;;;;;N;;;;; +E01E1;VARIATION SELECTOR-242;Mn;0;NSM;;;;;N;;;;; +E01E2;VARIATION SELECTOR-243;Mn;0;NSM;;;;;N;;;;; +E01E3;VARIATION SELECTOR-244;Mn;0;NSM;;;;;N;;;;; +E01E4;VARIATION SELECTOR-245;Mn;0;NSM;;;;;N;;;;; +E01E5;VARIATION SELECTOR-246;Mn;0;NSM;;;;;N;;;;; +E01E6;VARIATION SELECTOR-247;Mn;0;NSM;;;;;N;;;;; +E01E7;VARIATION SELECTOR-248;Mn;0;NSM;;;;;N;;;;; +E01E8;VARIATION SELECTOR-249;Mn;0;NSM;;;;;N;;;;; +E01E9;VARIATION SELECTOR-250;Mn;0;NSM;;;;;N;;;;; +E01EA;VARIATION SELECTOR-251;Mn;0;NSM;;;;;N;;;;; +E01EB;VARIATION SELECTOR-252;Mn;0;NSM;;;;;N;;;;; +E01EC;VARIATION SELECTOR-253;Mn;0;NSM;;;;;N;;;;; +E01ED;VARIATION SELECTOR-254;Mn;0;NSM;;;;;N;;;;; +E01EE;VARIATION SELECTOR-255;Mn;0;NSM;;;;;N;;;;; +E01EF;VARIATION SELECTOR-256;Mn;0;NSM;;;;;N;;;;; +F0000;;Co;0;L;;;;;N;;;;; +FFFFD;;Co;0;L;;;;;N;;;;; +100000;;Co;0;L;;;;;N;;;;; +10FFFD;;Co;0;L;;;;;N;;;;; diff --git a/util/import_bidi.py b/util/import_bidi.py new file mode 100644 index 000000000..543174ad9 --- /dev/null +++ b/util/import_bidi.py @@ -0,0 +1,52 @@ +#* +#* GRUB -- GRand Unified Bootloader +#* Copyright (C) 2010 Free Software Foundation, Inc. +#* +#* GRUB is free software: you can redistribute it and/or modify +#* it under the terms of the GNU General Public License as published by +#* the Free Software Foundation, either version 3 of the License, or +#* (at your option) any later version. +#* +#* GRUB is distributed in the hope that it will be useful, +#* but WITHOUT ANY WARRANTY; without even the implied warranty of +#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#* GNU General Public License for more details. +#* +#* You should have received a copy of the GNU General Public License +#* along with GRUB. If not, see . +#* + +import re +import sys +import os +import datetime + +if len (sys.argv) < 3: + print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) + exit (0) +infile = open (sys.argv[1], "r") +outfile = open (sys.argv[2], "w") +outfile.write ("#include \n") +outfile.write ("\n") +outfile.write ("struct grub_bidi_compact_range grub_bidi_compact[] = {\n") + +begin = -2 +last = -2 +lasttype = "X" +for line in infile: + sp = line.split (";") + cur = int (sp[0], 16) + curtype = sp[4] + if last + 1 != cur or curtype != lasttype: + if begin != -2 and lasttype != "L": + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s},\n" \ + % (begin, last, lasttype))) + begin = cur + last = cur + lasttype = curtype +if lasttype != "L": + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s},\n" \ + % (begin, last, lasttype))) +outfile.write ("{0, 0, 0},\n") + +outfile.write ("};") From 82b6651ab7492efb16a87b2ed988a010d8000986 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jan 2010 22:18:31 +0100 Subject: [PATCH 011/503] Add missing levels reversing --- font/font.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/font/font.c b/font/font.c index 8823bc6d3..cd5908d5c 100644 --- a/font/font.c +++ b/font/font.c @@ -1131,12 +1131,15 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, void revert (unsigned start, unsigned end) { grub_uint32_t t; - unsigned k; + unsigned k, tl; for (k = 0; k <= (end - start) / 2; k++) { t = no_markers[start+k]; no_markers[start+k] = no_markers[end-k]; no_markers[end-k] = t; + tl = levels[start+k]; + levels[start+k] = levels[end-k]; + levels[end-k] = tl; } } From 72f12cdcd93ddf25c74770d931b3e82b3711815b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 7 Jan 2010 16:37:53 +0100 Subject: [PATCH 012/503] Group combining diacritics --- autogen.sh | 2 +- font/font.c | 344 ++++++-- include/grub/{bidi.h => unicode.h} | 40 +- unidata.c | 1169 +++++++++++++++++----------- util/grub-mkfont.c | 3 + util/import_bidi.py | 52 -- util/import_unicode.py | 67 ++ 7 files changed, 1116 insertions(+), 561 deletions(-) rename include/grub/{bidi.h => unicode.h} (57%) delete mode 100644 util/import_bidi.py create mode 100644 util/import_unicode.py diff --git a/autogen.sh b/autogen.sh index 7aac1c534..5d0b5a282 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,7 +13,7 @@ echo timestamp > stamp-h.in python util/import_gcry.py lib/libgcrypt/ . -python util/import_bidi.py util/UnicodeData.txt unidata.c +python util/import_unicode.py util/UnicodeData.txt unidata.c for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do if test -e $rmk ; then diff --git a/font/font.c b/font/font.c index cd5908d5c..54b6a1048 100644 --- a/font/font.c +++ b/font/font.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #ifndef FONT_DEBUG #define FONT_DEBUG 0 @@ -882,7 +882,10 @@ grub_font_get_string_width (grub_font_t font, const char *str) grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; ) { glyph = grub_font_get_glyph_with_fallback (font, code); - width += glyph->device_width; + if (glyph) + width += glyph->device_width; + else + width += unknown_glyph->device_width; } return width; @@ -989,13 +992,210 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) } } - if (best_glyph) - return best_glyph; - else - /* Glyph not available in any font. Return unknown glyph. */ - return unknown_glyph; + return best_glyph; } +static struct grub_font_glyph * +grub_font_dup_glyph (struct grub_font_glyph *glyph) +{ + static struct grub_font_glyph *ret; + ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8); + if (!ret) + return NULL; + grub_memcpy (ret, glyph, sizeof (*ret) + + (glyph->width * glyph->height + 7) / 8); + return ret; +} + +/* FIXME: suboptimal. */ +static void +grub_font_blit_glyph (struct grub_font_glyph *target, + struct grub_font_glyph *src, + unsigned dx, unsigned dy) +{ + unsigned src_bit, tgt_bit, src_byte, tgt_byte; + unsigned i, j; + for (i = 0; i < src->height; i++) + { + src_bit = (src->width * i) % 8; + src_byte = (src->width * i) / 8; + tgt_bit = (target->width * (dy + i) + dx) % 8; + tgt_byte = (target->width * (dy + i) + dx) / 8; + for (j = 0; j < src->width; j++) + { + target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit) + & 0x80) >> tgt_bit; + src_bit++; + tgt_bit++; + if (src_bit == 8) + { + src_byte++; + src_bit = 0; + } + if (tgt_bit == 8) + { + tgt_byte++; + tgt_bit = 0; + } + } + } +} + +static inline enum grub_comb_type +get_comb_type (grub_uint32_t c) +{ + static grub_uint8_t *comb_types = NULL; + struct grub_unicode_compact_range *cur; + + if (!comb_types) + { + unsigned i; + comb_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (comb_types) + for (cur = grub_unicode_compact; cur->end; cur++) + for (i = cur->start; i <= cur->end + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + comb_types[i] = cur->comb_type; + else + grub_errno = GRUB_ERR_NONE; + } + + if (comb_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return comb_types[c]; + + for (cur = grub_unicode_compact; cur->end; cur++) + if (cur->start <= c && c <= cur->end) + return cur->comb_type; + + return GRUB_BIDI_TYPE_L; +} + +static struct grub_font_glyph * +grub_font_construct_glyph (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id) +{ + grub_font_t font; + grub_uint16_t width; + grub_uint16_t height; + grub_int16_t offset_x; + grub_int16_t offset_y; + grub_uint16_t device_width; + struct grub_font_glyph *main_glyph; + struct grub_font_glyph **combining_glyphs; + unsigned i; + struct grub_font_glyph *glyph; + + main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base); + + if (!main_glyph) + { + /* Glyph not available in any font. Return unknown glyph. */ + return grub_font_dup_glyph (unknown_glyph); + } + + if (!glyph_id->ncomb) + return grub_font_dup_glyph (main_glyph); + + combining_glyphs = grub_malloc (sizeof (combining_glyphs[0]) + * glyph_id->ncomb); + if (!combining_glyphs) + { + grub_errno = GRUB_ERR_NONE; + return grub_font_dup_glyph (main_glyph); + } + + font = main_glyph->font; + width = main_glyph->width; + height = main_glyph->height; + offset_x = main_glyph->offset_x; + offset_y = main_glyph->offset_y; + device_width = main_glyph->device_width; + + for (i = 0; i < glyph_id->ncomb; i++) + { + enum grub_comb_type combtype; + combining_glyphs[i] + = grub_font_get_glyph_with_fallback (font, glyph_id->combining[i]); + if (!combining_glyphs[i]) + continue; + combtype = get_comb_type (glyph_id->combining[i]); + switch (combtype) + { + default: + { + /* Default handling. Just draw combining character on top + of base character. + FIXME: support more unicode types correctly. + */ + grub_int16_t nx = main_glyph->device_width + + combining_glyphs[i]->offset_x; + + device_width += combining_glyphs[i]->device_width; + if (nx < offset_x) + { + width += offset_x - nx; + offset_x = nx; + } + if (offset_y > combining_glyphs[i]->offset_y) + { + height += offset_y - combining_glyphs[i]->offset_y; + offset_y = combining_glyphs[i]->offset_y; + } + if (nx + combining_glyphs[i]->width - offset_x >= width) + width = nx + combining_glyphs[i]->width - offset_x + 1; + if (height + < (combining_glyphs[i]->height + + combining_glyphs[i]->offset_y) - offset_y) + height = (combining_glyphs[i]->height + + combining_glyphs[i]->offset_y) - offset_y; + } + } + } + + glyph = grub_zalloc (sizeof (*glyph) + (width * height + 7) / 8); + if (!glyph) + { + grub_errno = GRUB_ERR_NONE; + return grub_font_dup_glyph (main_glyph); + } + + glyph->font = font; + glyph->width = width; + glyph->height = height; + glyph->offset_x = offset_x; + glyph->offset_y = offset_y; + glyph->device_width = device_width; + + grub_font_blit_glyph (glyph, main_glyph, main_glyph->offset_x - offset_x, + (height + offset_y) + - (main_glyph->height + main_glyph->offset_y)); + + for (i = 0; i < glyph_id->ncomb; i++) + { + enum grub_comb_type combtype; + if (!combining_glyphs[i]) + continue; + combtype = get_comb_type (glyph_id->combining[i]); + switch (combtype) + { + default: + { + /* Default handling. Just draw combining character on top + of base character. + FIXME: support more unicode types correctly. + */ + grub_font_blit_glyph (glyph, combining_glyphs[i], + main_glyph->device_width + + combining_glyphs[i]->offset_x - offset_x, + (height + offset_y) + - (combining_glyphs[i]->height + + combining_glyphs[i]->offset_y)); + } + } + } + + return glyph; +} /* Draw the specified glyph at (x, y). The y coordinate designates the baseline of the character, while the x coordinate designates the left @@ -1051,27 +1251,27 @@ static inline enum grub_bidi_type get_bidi_type (grub_uint32_t c) { static grub_uint8_t *bidi_types = NULL; - struct grub_bidi_compact_range *cur; + struct grub_unicode_compact_range *cur; if (!bidi_types) { unsigned i; - bidi_types = grub_zalloc (GRUB_BIDI_MAX_CACHED_UNICODE_CHAR); + bidi_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); if (bidi_types) - for (cur = grub_bidi_compact; cur->end; cur++) + for (cur = grub_unicode_compact; cur->end; cur++) for (i = cur->start; i <= cur->end - && i < GRUB_BIDI_MAX_CACHED_UNICODE_CHAR; i++) - bidi_types[i] = cur->type; + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + bidi_types[i] = cur->bidi_type; else grub_errno = GRUB_ERR_NONE; } - if (bidi_types && c < GRUB_BIDI_MAX_CACHED_UNICODE_CHAR) + if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) return bidi_types[c]; - for (cur = grub_bidi_compact; cur->end; cur++) + for (cur = grub_unicode_compact; cur->end; cur++) if (cur->start <= c && c <= cur->end) - return cur->type; + return cur->bidi_type; return GRUB_BIDI_TYPE_L; } @@ -1079,7 +1279,7 @@ get_bidi_type (grub_uint32_t c) static grub_ssize_t grub_err_bidi_logical_to_visual (grub_uint32_t *logical, grub_size_t logical_len, - grub_uint32_t **visual) + struct grub_unicode_glyph **visual_out) { enum grub_bidi_type type = GRUB_BIDI_TYPE_L; enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; @@ -1092,9 +1292,9 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, enum override_status stack_override[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; unsigned stack_depth = 0; unsigned invalid_pushes = 0; - unsigned no_markers_len = 0; + unsigned visual_len = 0; unsigned run_start, run_end; - grub_uint32_t *no_markers; + struct grub_unicode_glyph *visual; unsigned cur_level; auto void push_stack (unsigned new_override, unsigned new_level); @@ -1130,13 +1330,13 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, auto void revert (unsigned start, unsigned end); void revert (unsigned start, unsigned end) { - grub_uint32_t t; + struct grub_unicode_glyph t; unsigned k, tl; for (k = 0; k <= (end - start) / 2; k++) { - t = no_markers[start+k]; - no_markers[start+k] = no_markers[end-k]; - no_markers[end-k] = t; + t = visual[start+k]; + visual[start+k] = visual[end-k]; + visual[end-k] = t; tl = levels[start+k]; levels[start+k] = levels[end-k]; levels[end-k] = tl; @@ -1154,8 +1354,8 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, return -1; } - no_markers = grub_malloc (sizeof (resolved_types[0]) * logical_len); - if (!no_markers) + visual = grub_malloc (sizeof (visual[0]) * logical_len); + if (!visual) { grub_free (resolved_types); grub_free (levels); @@ -1178,6 +1378,27 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, cur_override = OVERRIDE_NEUTRAL; for (i = 0; i < logical_len; i++) { + /* Variation selectors >= 17 are outside of BMP and SMP. + Handle variation selectors first to avoid potentially costly lookups. + */ + if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1 + && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16) + { + if (!visual_len) + continue; + visual[visual_len - 1].variant + = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1; + } + if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17 + && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256) + { + if (!visual_len) + continue; + visual[visual_len - 1].variant + = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17; + continue; + } + type = get_bidi_type (logical[i]); switch (type) { @@ -1199,28 +1420,54 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, case GRUB_BIDI_TYPE_BN: break; default: - levels[no_markers_len] = cur_level; - if (cur_override != OVERRIDE_NEUTRAL) - resolved_types[no_markers_len] = - (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L : GRUB_BIDI_TYPE_R; - else - resolved_types[no_markers_len] = type; - no_markers[no_markers_len] = logical[i]; - no_markers_len++; + { + enum grub_comb_type comb_type; + comb_type = get_comb_type (logical[i]); + if (comb_type) + { + grub_uint32_t *n; + if (!visual_len) + break; + n = grub_realloc (visual[visual_len - 1].combining, + sizeof (grub_uint32_t) + * (visual[visual_len - 1].ncomb + 1)); + if (!n) + { + grub_errno = GRUB_ERR_NONE; + break; + } + visual[visual_len - 1].combining = n; + visual[visual_len - 1].combining[visual[visual_len - 1].ncomb] + = logical[i]; + visual[visual_len - 1].ncomb++; + break; + } + levels[visual_len] = cur_level; + if (cur_override != OVERRIDE_NEUTRAL) + resolved_types[visual_len] = + (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L : GRUB_BIDI_TYPE_R; + else + resolved_types[visual_len] = type; + visual[visual_len].base = logical[i]; + visual[visual_len].variant = 0; + visual[visual_len].ncomb = 0; + visual[visual_len].combining = NULL; + visual_len++; + } } } - for (run_start = 0; run_start < no_markers_len; run_start = run_end) + for (run_start = 0; run_start < visual_len; run_start = run_end) { unsigned prev_level, next_level, cur_run_level; unsigned last_type, last_strong_type; - for (run_end = run_start; run_end < no_markers_len && + for (run_end = run_start; run_end < visual_len && levels[run_end] == levels[run_start]; run_end++); if (run_start == 0) prev_level = base_level; else prev_level = levels[run_start - 1]; - if (run_end == no_markers_len) + if (run_end == visual_len) next_level = base_level; else next_level = levels[run_end]; @@ -1350,7 +1597,7 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, } } - for (i = 0; i < no_markers_len; i++) + for (i = 0; i < visual_len; i++) { if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R) { @@ -1377,7 +1624,7 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, unsigned min_odd_level = 0xffffffff; unsigned max_level = 0; unsigned j; - for (i = 0; i < no_markers_len; i++) + for (i = 0; i < visual_len; i++) { if (levels[i] > max_level) max_level = levels[i]; @@ -1387,11 +1634,11 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, for (j = max_level; j >= min_odd_level; j--) { unsigned in = 0; - for (i = 0; i < no_markers_len; i++) + for (i = 0; i < visual_len; i++) { if (i != 0 && levels[i] >= j && levels[i-1] < j) in = i; - if (levels[i] >= j && (i + 1 == no_markers_len || levels[i+1] < j)) + if (levels[i] >= j && (i + 1 == visual_len || levels[i+1] < j)) revert (in, i); } } @@ -1399,8 +1646,8 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, grub_free (levels); - *visual = no_markers; - return no_markers_len; + *visual_out = visual; + return visual_len; } /* Draw a UTF-8 string of text on the current video render target. @@ -1415,8 +1662,9 @@ grub_font_draw_string (const char *str, grub_font_t font, { int x; struct grub_font_glyph *glyph; - grub_uint32_t *logical, *visual, *ptr; + grub_uint32_t *logical; grub_ssize_t logical_len, visual_len; + struct grub_unicode_glyph *visual, *ptr; logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); if (logical_len < 0) @@ -1429,10 +1677,14 @@ grub_font_draw_string (const char *str, grub_font_t font, for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++) { - glyph = grub_font_get_glyph_with_fallback (font, *ptr); - if (grub_font_draw_glyph (glyph, color, x, baseline_y) - != GRUB_ERR_NONE) - return grub_errno; + grub_err_t err; + glyph = grub_font_construct_glyph (font, ptr); + if (!glyph) + return grub_errno; + err = grub_font_draw_glyph (glyph, color, x, baseline_y); + grub_free (glyph); + if (err) + return err; x += glyph->device_width; } diff --git a/include/grub/bidi.h b/include/grub/unicode.h similarity index 57% rename from include/grub/bidi.h rename to include/grub/unicode.h index 8612d6e24..79d553eec 100644 --- a/include/grub/bidi.h +++ b/include/grub/unicode.h @@ -21,11 +21,12 @@ #include -struct grub_bidi_compact_range +struct grub_unicode_compact_range { - grub_uint32_t start:24; - grub_uint32_t end:24; - grub_uint8_t type; + grub_uint32_t start:21; + grub_uint32_t end:21; + grub_uint8_t bidi_type:5; + grub_uint8_t comb_type; } __attribute__ ((packed)); enum grub_bidi_type @@ -51,9 +52,36 @@ enum grub_bidi_type GRUB_BIDI_TYPE_ON }; -extern struct grub_bidi_compact_range grub_bidi_compact[]; +enum grub_comb_type + { + GRUB_UNICODE_STACK_BELOW = 220, + GRUB_UNICODE_STACK_ABOVE = 230, + /* If combining nature is indicated only by class and + not "combining type". */ + GRUB_UNICODE_COMB_ME = 253, + GRUB_UNICODE_COMB_MC = 254, + GRUB_UNICODE_COMB_MN = 255, + }; -#define GRUB_BIDI_MAX_CACHED_UNICODE_CHAR 0x20000 +/* This structure describes a glyph as opposed to character. */ +struct grub_unicode_glyph +{ + grub_uint32_t base; + /* Unicode permits 256 variation selectors but since we need a value + for "default" we have to use grub_uint16_t. */ + grub_uint16_t variant; + grub_size_t ncomb; + grub_uint32_t *combining; +}; + +#define GRUB_UNICODE_VARIATION_SELECTOR_1 0xfe00 +#define GRUB_UNICODE_VARIATION_SELECTOR_16 0xfe0f +#define GRUB_UNICODE_VARIATION_SELECTOR_17 0xe0100 +#define GRUB_UNICODE_VARIATION_SELECTOR_256 0xe01ef + +extern struct grub_unicode_compact_range grub_unicode_compact[]; + +#define GRUB_UNICODE_MAX_CACHED_CHAR 0x20000 /* Unicode mandates an arbitrary limit. */ #define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61 diff --git a/unidata.c b/unidata.c index f4467c920..02d0f9712 100644 --- a/unidata.c +++ b/unidata.c @@ -1,458 +1,715 @@ -#include +#include -struct grub_bidi_compact_range grub_bidi_compact[] = { -{0x0, 0x8, GRUB_BIDI_TYPE_BN}, -{0x9, 0x9, GRUB_BIDI_TYPE_S}, -{0xa, 0xa, GRUB_BIDI_TYPE_B}, -{0xb, 0xb, GRUB_BIDI_TYPE_S}, -{0xc, 0xc, GRUB_BIDI_TYPE_WS}, -{0xd, 0xd, GRUB_BIDI_TYPE_B}, -{0xe, 0x1b, GRUB_BIDI_TYPE_BN}, -{0x1c, 0x1e, GRUB_BIDI_TYPE_B}, -{0x1f, 0x1f, GRUB_BIDI_TYPE_S}, -{0x20, 0x20, GRUB_BIDI_TYPE_WS}, -{0x21, 0x22, GRUB_BIDI_TYPE_ON}, -{0x23, 0x25, GRUB_BIDI_TYPE_ET}, -{0x26, 0x2a, GRUB_BIDI_TYPE_ON}, -{0x2b, 0x2b, GRUB_BIDI_TYPE_ES}, -{0x2c, 0x2c, GRUB_BIDI_TYPE_CS}, -{0x2d, 0x2d, GRUB_BIDI_TYPE_ES}, -{0x2e, 0x2f, GRUB_BIDI_TYPE_CS}, -{0x30, 0x39, GRUB_BIDI_TYPE_EN}, -{0x3a, 0x3a, GRUB_BIDI_TYPE_CS}, -{0x3b, 0x40, GRUB_BIDI_TYPE_ON}, -{0x5b, 0x60, GRUB_BIDI_TYPE_ON}, -{0x7b, 0x7e, GRUB_BIDI_TYPE_ON}, -{0x7f, 0x84, GRUB_BIDI_TYPE_BN}, -{0x85, 0x85, GRUB_BIDI_TYPE_B}, -{0x86, 0x9f, GRUB_BIDI_TYPE_BN}, -{0xa0, 0xa0, GRUB_BIDI_TYPE_CS}, -{0xa1, 0xa1, GRUB_BIDI_TYPE_ON}, -{0xa2, 0xa5, GRUB_BIDI_TYPE_ET}, -{0xa6, 0xa9, GRUB_BIDI_TYPE_ON}, -{0xab, 0xac, GRUB_BIDI_TYPE_ON}, -{0xad, 0xad, GRUB_BIDI_TYPE_BN}, -{0xae, 0xaf, GRUB_BIDI_TYPE_ON}, -{0xb0, 0xb1, GRUB_BIDI_TYPE_ET}, -{0xb2, 0xb3, GRUB_BIDI_TYPE_EN}, -{0xb4, 0xb4, GRUB_BIDI_TYPE_ON}, -{0xb6, 0xb8, GRUB_BIDI_TYPE_ON}, -{0xb9, 0xb9, GRUB_BIDI_TYPE_EN}, -{0xbb, 0xbf, GRUB_BIDI_TYPE_ON}, -{0xd7, 0xd7, GRUB_BIDI_TYPE_ON}, -{0xf7, 0xf7, GRUB_BIDI_TYPE_ON}, -{0x2b9, 0x2ba, GRUB_BIDI_TYPE_ON}, -{0x2c2, 0x2cf, GRUB_BIDI_TYPE_ON}, -{0x2d2, 0x2df, GRUB_BIDI_TYPE_ON}, -{0x2e5, 0x2ed, GRUB_BIDI_TYPE_ON}, -{0x2ef, 0x2ff, GRUB_BIDI_TYPE_ON}, -{0x300, 0x36f, GRUB_BIDI_TYPE_NSM}, -{0x374, 0x375, GRUB_BIDI_TYPE_ON}, -{0x37e, 0x37e, GRUB_BIDI_TYPE_ON}, -{0x384, 0x385, GRUB_BIDI_TYPE_ON}, -{0x387, 0x387, GRUB_BIDI_TYPE_ON}, -{0x3f6, 0x3f6, GRUB_BIDI_TYPE_ON}, -{0x483, 0x489, GRUB_BIDI_TYPE_NSM}, -{0x58a, 0x58a, GRUB_BIDI_TYPE_ON}, -{0x591, 0x5bd, GRUB_BIDI_TYPE_NSM}, -{0x5be, 0x5be, GRUB_BIDI_TYPE_R}, -{0x5bf, 0x5bf, GRUB_BIDI_TYPE_NSM}, -{0x5c0, 0x5c0, GRUB_BIDI_TYPE_R}, -{0x5c1, 0x5c2, GRUB_BIDI_TYPE_NSM}, -{0x5c3, 0x5c3, GRUB_BIDI_TYPE_R}, -{0x5c4, 0x5c5, GRUB_BIDI_TYPE_NSM}, -{0x5c6, 0x5c6, GRUB_BIDI_TYPE_R}, -{0x5c7, 0x5c7, GRUB_BIDI_TYPE_NSM}, -{0x5d0, 0x5ea, GRUB_BIDI_TYPE_R}, -{0x5f0, 0x5f4, GRUB_BIDI_TYPE_R}, -{0x600, 0x603, GRUB_BIDI_TYPE_AN}, -{0x606, 0x607, GRUB_BIDI_TYPE_ON}, -{0x608, 0x608, GRUB_BIDI_TYPE_AL}, -{0x609, 0x60a, GRUB_BIDI_TYPE_ET}, -{0x60b, 0x60b, GRUB_BIDI_TYPE_AL}, -{0x60c, 0x60c, GRUB_BIDI_TYPE_CS}, -{0x60d, 0x60d, GRUB_BIDI_TYPE_AL}, -{0x60e, 0x60f, GRUB_BIDI_TYPE_ON}, -{0x610, 0x61a, GRUB_BIDI_TYPE_NSM}, -{0x61b, 0x61b, GRUB_BIDI_TYPE_AL}, -{0x61e, 0x61f, GRUB_BIDI_TYPE_AL}, -{0x621, 0x64a, GRUB_BIDI_TYPE_AL}, -{0x64b, 0x65e, GRUB_BIDI_TYPE_NSM}, -{0x660, 0x669, GRUB_BIDI_TYPE_AN}, -{0x66a, 0x66a, GRUB_BIDI_TYPE_ET}, -{0x66b, 0x66c, GRUB_BIDI_TYPE_AN}, -{0x66d, 0x66f, GRUB_BIDI_TYPE_AL}, -{0x670, 0x670, GRUB_BIDI_TYPE_NSM}, -{0x671, 0x6d5, GRUB_BIDI_TYPE_AL}, -{0x6d6, 0x6dc, GRUB_BIDI_TYPE_NSM}, -{0x6dd, 0x6dd, GRUB_BIDI_TYPE_AN}, -{0x6de, 0x6e4, GRUB_BIDI_TYPE_NSM}, -{0x6e5, 0x6e6, GRUB_BIDI_TYPE_AL}, -{0x6e7, 0x6e8, GRUB_BIDI_TYPE_NSM}, -{0x6e9, 0x6e9, GRUB_BIDI_TYPE_ON}, -{0x6ea, 0x6ed, GRUB_BIDI_TYPE_NSM}, -{0x6ee, 0x6ef, GRUB_BIDI_TYPE_AL}, -{0x6f0, 0x6f9, GRUB_BIDI_TYPE_EN}, -{0x6fa, 0x70d, GRUB_BIDI_TYPE_AL}, -{0x70f, 0x70f, GRUB_BIDI_TYPE_BN}, -{0x710, 0x710, GRUB_BIDI_TYPE_AL}, -{0x711, 0x711, GRUB_BIDI_TYPE_NSM}, -{0x712, 0x72f, GRUB_BIDI_TYPE_AL}, -{0x730, 0x74a, GRUB_BIDI_TYPE_NSM}, -{0x74d, 0x7a5, GRUB_BIDI_TYPE_AL}, -{0x7a6, 0x7b0, GRUB_BIDI_TYPE_NSM}, -{0x7b1, 0x7b1, GRUB_BIDI_TYPE_AL}, -{0x7c0, 0x7ea, GRUB_BIDI_TYPE_R}, -{0x7eb, 0x7f3, GRUB_BIDI_TYPE_NSM}, -{0x7f4, 0x7f5, GRUB_BIDI_TYPE_R}, -{0x7f6, 0x7f9, GRUB_BIDI_TYPE_ON}, -{0x7fa, 0x7fa, GRUB_BIDI_TYPE_R}, -{0x901, 0x902, GRUB_BIDI_TYPE_NSM}, -{0x93c, 0x93c, GRUB_BIDI_TYPE_NSM}, -{0x941, 0x948, GRUB_BIDI_TYPE_NSM}, -{0x94d, 0x94d, GRUB_BIDI_TYPE_NSM}, -{0x951, 0x954, GRUB_BIDI_TYPE_NSM}, -{0x962, 0x963, GRUB_BIDI_TYPE_NSM}, -{0x981, 0x981, GRUB_BIDI_TYPE_NSM}, -{0x9bc, 0x9bc, GRUB_BIDI_TYPE_NSM}, -{0x9c1, 0x9c4, GRUB_BIDI_TYPE_NSM}, -{0x9cd, 0x9cd, GRUB_BIDI_TYPE_NSM}, -{0x9e2, 0x9e3, GRUB_BIDI_TYPE_NSM}, -{0x9f2, 0x9f3, GRUB_BIDI_TYPE_ET}, -{0xa01, 0xa02, GRUB_BIDI_TYPE_NSM}, -{0xa3c, 0xa3c, GRUB_BIDI_TYPE_NSM}, -{0xa41, 0xa42, GRUB_BIDI_TYPE_NSM}, -{0xa47, 0xa48, GRUB_BIDI_TYPE_NSM}, -{0xa4b, 0xa4d, GRUB_BIDI_TYPE_NSM}, -{0xa51, 0xa51, GRUB_BIDI_TYPE_NSM}, -{0xa70, 0xa71, GRUB_BIDI_TYPE_NSM}, -{0xa75, 0xa75, GRUB_BIDI_TYPE_NSM}, -{0xa81, 0xa82, GRUB_BIDI_TYPE_NSM}, -{0xabc, 0xabc, GRUB_BIDI_TYPE_NSM}, -{0xac1, 0xac5, GRUB_BIDI_TYPE_NSM}, -{0xac7, 0xac8, GRUB_BIDI_TYPE_NSM}, -{0xacd, 0xacd, GRUB_BIDI_TYPE_NSM}, -{0xae2, 0xae3, GRUB_BIDI_TYPE_NSM}, -{0xaf1, 0xaf1, GRUB_BIDI_TYPE_ET}, -{0xb01, 0xb01, GRUB_BIDI_TYPE_NSM}, -{0xb3c, 0xb3c, GRUB_BIDI_TYPE_NSM}, -{0xb3f, 0xb3f, GRUB_BIDI_TYPE_NSM}, -{0xb41, 0xb44, GRUB_BIDI_TYPE_NSM}, -{0xb4d, 0xb4d, GRUB_BIDI_TYPE_NSM}, -{0xb56, 0xb56, GRUB_BIDI_TYPE_NSM}, -{0xb62, 0xb63, GRUB_BIDI_TYPE_NSM}, -{0xb82, 0xb82, GRUB_BIDI_TYPE_NSM}, -{0xbc0, 0xbc0, GRUB_BIDI_TYPE_NSM}, -{0xbcd, 0xbcd, GRUB_BIDI_TYPE_NSM}, -{0xbf3, 0xbf8, GRUB_BIDI_TYPE_ON}, -{0xbf9, 0xbf9, GRUB_BIDI_TYPE_ET}, -{0xbfa, 0xbfa, GRUB_BIDI_TYPE_ON}, -{0xc3e, 0xc40, GRUB_BIDI_TYPE_NSM}, -{0xc46, 0xc48, GRUB_BIDI_TYPE_NSM}, -{0xc4a, 0xc4d, GRUB_BIDI_TYPE_NSM}, -{0xc55, 0xc56, GRUB_BIDI_TYPE_NSM}, -{0xc62, 0xc63, GRUB_BIDI_TYPE_NSM}, -{0xc78, 0xc7e, GRUB_BIDI_TYPE_ON}, -{0xcbc, 0xcbc, GRUB_BIDI_TYPE_NSM}, -{0xccc, 0xccd, GRUB_BIDI_TYPE_NSM}, -{0xce2, 0xce3, GRUB_BIDI_TYPE_NSM}, -{0xcf1, 0xcf2, GRUB_BIDI_TYPE_ON}, -{0xd41, 0xd44, GRUB_BIDI_TYPE_NSM}, -{0xd4d, 0xd4d, GRUB_BIDI_TYPE_NSM}, -{0xd62, 0xd63, GRUB_BIDI_TYPE_NSM}, -{0xdca, 0xdca, GRUB_BIDI_TYPE_NSM}, -{0xdd2, 0xdd4, GRUB_BIDI_TYPE_NSM}, -{0xdd6, 0xdd6, GRUB_BIDI_TYPE_NSM}, -{0xe31, 0xe31, GRUB_BIDI_TYPE_NSM}, -{0xe34, 0xe3a, GRUB_BIDI_TYPE_NSM}, -{0xe3f, 0xe3f, GRUB_BIDI_TYPE_ET}, -{0xe47, 0xe4e, GRUB_BIDI_TYPE_NSM}, -{0xeb1, 0xeb1, GRUB_BIDI_TYPE_NSM}, -{0xeb4, 0xeb9, GRUB_BIDI_TYPE_NSM}, -{0xebb, 0xebc, GRUB_BIDI_TYPE_NSM}, -{0xec8, 0xecd, GRUB_BIDI_TYPE_NSM}, -{0xf18, 0xf19, GRUB_BIDI_TYPE_NSM}, -{0xf35, 0xf35, GRUB_BIDI_TYPE_NSM}, -{0xf37, 0xf37, GRUB_BIDI_TYPE_NSM}, -{0xf39, 0xf39, GRUB_BIDI_TYPE_NSM}, -{0xf3a, 0xf3d, GRUB_BIDI_TYPE_ON}, -{0xf71, 0xf7e, GRUB_BIDI_TYPE_NSM}, -{0xf80, 0xf84, GRUB_BIDI_TYPE_NSM}, -{0xf86, 0xf87, GRUB_BIDI_TYPE_NSM}, -{0xf90, 0xf97, GRUB_BIDI_TYPE_NSM}, -{0xf99, 0xfbc, GRUB_BIDI_TYPE_NSM}, -{0xfc6, 0xfc6, GRUB_BIDI_TYPE_NSM}, -{0x102d, 0x1030, GRUB_BIDI_TYPE_NSM}, -{0x1032, 0x1037, GRUB_BIDI_TYPE_NSM}, -{0x1039, 0x103a, GRUB_BIDI_TYPE_NSM}, -{0x103d, 0x103e, GRUB_BIDI_TYPE_NSM}, -{0x1058, 0x1059, GRUB_BIDI_TYPE_NSM}, -{0x105e, 0x1060, GRUB_BIDI_TYPE_NSM}, -{0x1071, 0x1074, GRUB_BIDI_TYPE_NSM}, -{0x1082, 0x1082, GRUB_BIDI_TYPE_NSM}, -{0x1085, 0x1086, GRUB_BIDI_TYPE_NSM}, -{0x108d, 0x108d, GRUB_BIDI_TYPE_NSM}, -{0x135f, 0x135f, GRUB_BIDI_TYPE_NSM}, -{0x1390, 0x1399, GRUB_BIDI_TYPE_ON}, -{0x1680, 0x1680, GRUB_BIDI_TYPE_WS}, -{0x169b, 0x169c, GRUB_BIDI_TYPE_ON}, -{0x1712, 0x1714, GRUB_BIDI_TYPE_NSM}, -{0x1732, 0x1734, GRUB_BIDI_TYPE_NSM}, -{0x1752, 0x1753, GRUB_BIDI_TYPE_NSM}, -{0x1772, 0x1773, GRUB_BIDI_TYPE_NSM}, -{0x17b7, 0x17bd, GRUB_BIDI_TYPE_NSM}, -{0x17c6, 0x17c6, GRUB_BIDI_TYPE_NSM}, -{0x17c9, 0x17d3, GRUB_BIDI_TYPE_NSM}, -{0x17db, 0x17db, GRUB_BIDI_TYPE_ET}, -{0x17dd, 0x17dd, GRUB_BIDI_TYPE_NSM}, -{0x17f0, 0x17f9, GRUB_BIDI_TYPE_ON}, -{0x1800, 0x180a, GRUB_BIDI_TYPE_ON}, -{0x180b, 0x180d, GRUB_BIDI_TYPE_NSM}, -{0x180e, 0x180e, GRUB_BIDI_TYPE_WS}, -{0x18a9, 0x18a9, GRUB_BIDI_TYPE_NSM}, -{0x1920, 0x1922, GRUB_BIDI_TYPE_NSM}, -{0x1927, 0x1928, GRUB_BIDI_TYPE_NSM}, -{0x1932, 0x1932, GRUB_BIDI_TYPE_NSM}, -{0x1939, 0x193b, GRUB_BIDI_TYPE_NSM}, -{0x1940, 0x1940, GRUB_BIDI_TYPE_ON}, -{0x1944, 0x1945, GRUB_BIDI_TYPE_ON}, -{0x19de, 0x19ff, GRUB_BIDI_TYPE_ON}, -{0x1a17, 0x1a18, GRUB_BIDI_TYPE_NSM}, -{0x1b00, 0x1b03, GRUB_BIDI_TYPE_NSM}, -{0x1b34, 0x1b34, GRUB_BIDI_TYPE_NSM}, -{0x1b36, 0x1b3a, GRUB_BIDI_TYPE_NSM}, -{0x1b3c, 0x1b3c, GRUB_BIDI_TYPE_NSM}, -{0x1b42, 0x1b42, GRUB_BIDI_TYPE_NSM}, -{0x1b6b, 0x1b73, GRUB_BIDI_TYPE_NSM}, -{0x1b80, 0x1b81, GRUB_BIDI_TYPE_NSM}, -{0x1ba2, 0x1ba5, GRUB_BIDI_TYPE_NSM}, -{0x1ba8, 0x1ba9, GRUB_BIDI_TYPE_NSM}, -{0x1c2c, 0x1c33, GRUB_BIDI_TYPE_NSM}, -{0x1c36, 0x1c37, GRUB_BIDI_TYPE_NSM}, -{0x1dc0, 0x1de6, GRUB_BIDI_TYPE_NSM}, -{0x1dfe, 0x1dff, GRUB_BIDI_TYPE_NSM}, -{0x1fbd, 0x1fbd, GRUB_BIDI_TYPE_ON}, -{0x1fbf, 0x1fc1, GRUB_BIDI_TYPE_ON}, -{0x1fcd, 0x1fcf, GRUB_BIDI_TYPE_ON}, -{0x1fdd, 0x1fdf, GRUB_BIDI_TYPE_ON}, -{0x1fed, 0x1fef, GRUB_BIDI_TYPE_ON}, -{0x1ffd, 0x1ffe, GRUB_BIDI_TYPE_ON}, -{0x2000, 0x200a, GRUB_BIDI_TYPE_WS}, -{0x200b, 0x200d, GRUB_BIDI_TYPE_BN}, -{0x200f, 0x200f, GRUB_BIDI_TYPE_R}, -{0x2010, 0x2027, GRUB_BIDI_TYPE_ON}, -{0x2028, 0x2028, GRUB_BIDI_TYPE_WS}, -{0x2029, 0x2029, GRUB_BIDI_TYPE_B}, -{0x202a, 0x202a, GRUB_BIDI_TYPE_LRE}, -{0x202b, 0x202b, GRUB_BIDI_TYPE_RLE}, -{0x202c, 0x202c, GRUB_BIDI_TYPE_PDF}, -{0x202d, 0x202d, GRUB_BIDI_TYPE_LRO}, -{0x202e, 0x202e, GRUB_BIDI_TYPE_RLO}, -{0x202f, 0x202f, GRUB_BIDI_TYPE_CS}, -{0x2030, 0x2034, GRUB_BIDI_TYPE_ET}, -{0x2035, 0x2043, GRUB_BIDI_TYPE_ON}, -{0x2044, 0x2044, GRUB_BIDI_TYPE_CS}, -{0x2045, 0x205e, GRUB_BIDI_TYPE_ON}, -{0x205f, 0x205f, GRUB_BIDI_TYPE_WS}, -{0x2060, 0x2064, GRUB_BIDI_TYPE_BN}, -{0x206a, 0x206f, GRUB_BIDI_TYPE_BN}, -{0x2070, 0x2070, GRUB_BIDI_TYPE_EN}, -{0x2074, 0x2079, GRUB_BIDI_TYPE_EN}, -{0x207a, 0x207b, GRUB_BIDI_TYPE_ES}, -{0x207c, 0x207e, GRUB_BIDI_TYPE_ON}, -{0x2080, 0x2089, GRUB_BIDI_TYPE_EN}, -{0x208a, 0x208b, GRUB_BIDI_TYPE_ES}, -{0x208c, 0x208e, GRUB_BIDI_TYPE_ON}, -{0x20a0, 0x20b5, GRUB_BIDI_TYPE_ET}, -{0x20d0, 0x20f0, GRUB_BIDI_TYPE_NSM}, -{0x2100, 0x2101, GRUB_BIDI_TYPE_ON}, -{0x2103, 0x2106, GRUB_BIDI_TYPE_ON}, -{0x2108, 0x2109, GRUB_BIDI_TYPE_ON}, -{0x2114, 0x2114, GRUB_BIDI_TYPE_ON}, -{0x2116, 0x2118, GRUB_BIDI_TYPE_ON}, -{0x211e, 0x2123, GRUB_BIDI_TYPE_ON}, -{0x2125, 0x2125, GRUB_BIDI_TYPE_ON}, -{0x2127, 0x2127, GRUB_BIDI_TYPE_ON}, -{0x2129, 0x2129, GRUB_BIDI_TYPE_ON}, -{0x212e, 0x212e, GRUB_BIDI_TYPE_ET}, -{0x213a, 0x213b, GRUB_BIDI_TYPE_ON}, -{0x2140, 0x2144, GRUB_BIDI_TYPE_ON}, -{0x214a, 0x214d, GRUB_BIDI_TYPE_ON}, -{0x2153, 0x215f, GRUB_BIDI_TYPE_ON}, -{0x2190, 0x2211, GRUB_BIDI_TYPE_ON}, -{0x2212, 0x2212, GRUB_BIDI_TYPE_ES}, -{0x2213, 0x2213, GRUB_BIDI_TYPE_ET}, -{0x2214, 0x2335, GRUB_BIDI_TYPE_ON}, -{0x237b, 0x2394, GRUB_BIDI_TYPE_ON}, -{0x2396, 0x23e7, GRUB_BIDI_TYPE_ON}, -{0x2400, 0x2426, GRUB_BIDI_TYPE_ON}, -{0x2440, 0x244a, GRUB_BIDI_TYPE_ON}, -{0x2460, 0x2487, GRUB_BIDI_TYPE_ON}, -{0x2488, 0x249b, GRUB_BIDI_TYPE_EN}, -{0x24ea, 0x269d, GRUB_BIDI_TYPE_ON}, -{0x26a0, 0x26ab, GRUB_BIDI_TYPE_ON}, -{0x26ad, 0x26bc, GRUB_BIDI_TYPE_ON}, -{0x26c0, 0x26c3, GRUB_BIDI_TYPE_ON}, -{0x2701, 0x2704, GRUB_BIDI_TYPE_ON}, -{0x2706, 0x2709, GRUB_BIDI_TYPE_ON}, -{0x270c, 0x2727, GRUB_BIDI_TYPE_ON}, -{0x2729, 0x274b, GRUB_BIDI_TYPE_ON}, -{0x274d, 0x274d, GRUB_BIDI_TYPE_ON}, -{0x274f, 0x2752, GRUB_BIDI_TYPE_ON}, -{0x2756, 0x2756, GRUB_BIDI_TYPE_ON}, -{0x2758, 0x275e, GRUB_BIDI_TYPE_ON}, -{0x2761, 0x2794, GRUB_BIDI_TYPE_ON}, -{0x2798, 0x27af, GRUB_BIDI_TYPE_ON}, -{0x27b1, 0x27be, GRUB_BIDI_TYPE_ON}, -{0x27c0, 0x27ca, GRUB_BIDI_TYPE_ON}, -{0x27cc, 0x27cc, GRUB_BIDI_TYPE_ON}, -{0x27d0, 0x27ff, GRUB_BIDI_TYPE_ON}, -{0x2900, 0x2b4c, GRUB_BIDI_TYPE_ON}, -{0x2b50, 0x2b54, GRUB_BIDI_TYPE_ON}, -{0x2ce5, 0x2cea, GRUB_BIDI_TYPE_ON}, -{0x2cf9, 0x2cff, GRUB_BIDI_TYPE_ON}, -{0x2de0, 0x2dff, GRUB_BIDI_TYPE_NSM}, -{0x2e00, 0x2e30, GRUB_BIDI_TYPE_ON}, -{0x2e80, 0x2e99, GRUB_BIDI_TYPE_ON}, -{0x2e9b, 0x2ef3, GRUB_BIDI_TYPE_ON}, -{0x2f00, 0x2fd5, GRUB_BIDI_TYPE_ON}, -{0x2ff0, 0x2ffb, GRUB_BIDI_TYPE_ON}, -{0x3000, 0x3000, GRUB_BIDI_TYPE_WS}, -{0x3001, 0x3004, GRUB_BIDI_TYPE_ON}, -{0x3008, 0x3020, GRUB_BIDI_TYPE_ON}, -{0x302a, 0x302f, GRUB_BIDI_TYPE_NSM}, -{0x3030, 0x3030, GRUB_BIDI_TYPE_ON}, -{0x3036, 0x3037, GRUB_BIDI_TYPE_ON}, -{0x303d, 0x303f, GRUB_BIDI_TYPE_ON}, -{0x3099, 0x309a, GRUB_BIDI_TYPE_NSM}, -{0x309b, 0x309c, GRUB_BIDI_TYPE_ON}, -{0x30a0, 0x30a0, GRUB_BIDI_TYPE_ON}, -{0x30fb, 0x30fb, GRUB_BIDI_TYPE_ON}, -{0x31c0, 0x31e3, GRUB_BIDI_TYPE_ON}, -{0x321d, 0x321e, GRUB_BIDI_TYPE_ON}, -{0x3250, 0x325f, GRUB_BIDI_TYPE_ON}, -{0x327c, 0x327e, GRUB_BIDI_TYPE_ON}, -{0x32b1, 0x32bf, GRUB_BIDI_TYPE_ON}, -{0x32cc, 0x32cf, GRUB_BIDI_TYPE_ON}, -{0x3377, 0x337a, GRUB_BIDI_TYPE_ON}, -{0x33de, 0x33df, GRUB_BIDI_TYPE_ON}, -{0x33ff, 0x33ff, GRUB_BIDI_TYPE_ON}, -{0x4dc0, 0x4dff, GRUB_BIDI_TYPE_ON}, -{0xa490, 0xa4c6, GRUB_BIDI_TYPE_ON}, -{0xa60d, 0xa60f, GRUB_BIDI_TYPE_ON}, -{0xa66f, 0xa672, GRUB_BIDI_TYPE_NSM}, -{0xa673, 0xa673, GRUB_BIDI_TYPE_ON}, -{0xa67c, 0xa67d, GRUB_BIDI_TYPE_NSM}, -{0xa67e, 0xa67f, GRUB_BIDI_TYPE_ON}, -{0xa700, 0xa721, GRUB_BIDI_TYPE_ON}, -{0xa788, 0xa788, GRUB_BIDI_TYPE_ON}, -{0xa802, 0xa802, GRUB_BIDI_TYPE_NSM}, -{0xa806, 0xa806, GRUB_BIDI_TYPE_NSM}, -{0xa80b, 0xa80b, GRUB_BIDI_TYPE_NSM}, -{0xa825, 0xa826, GRUB_BIDI_TYPE_NSM}, -{0xa828, 0xa82b, GRUB_BIDI_TYPE_ON}, -{0xa874, 0xa877, GRUB_BIDI_TYPE_ON}, -{0xa8c4, 0xa8c4, GRUB_BIDI_TYPE_NSM}, -{0xa926, 0xa92d, GRUB_BIDI_TYPE_NSM}, -{0xa947, 0xa951, GRUB_BIDI_TYPE_NSM}, -{0xaa29, 0xaa2e, GRUB_BIDI_TYPE_NSM}, -{0xaa31, 0xaa32, GRUB_BIDI_TYPE_NSM}, -{0xaa35, 0xaa36, GRUB_BIDI_TYPE_NSM}, -{0xaa43, 0xaa43, GRUB_BIDI_TYPE_NSM}, -{0xaa4c, 0xaa4c, GRUB_BIDI_TYPE_NSM}, -{0xfb1d, 0xfb1d, GRUB_BIDI_TYPE_R}, -{0xfb1e, 0xfb1e, GRUB_BIDI_TYPE_NSM}, -{0xfb1f, 0xfb28, GRUB_BIDI_TYPE_R}, -{0xfb29, 0xfb29, GRUB_BIDI_TYPE_ES}, -{0xfb2a, 0xfb36, GRUB_BIDI_TYPE_R}, -{0xfb38, 0xfb3c, GRUB_BIDI_TYPE_R}, -{0xfb3e, 0xfb3e, GRUB_BIDI_TYPE_R}, -{0xfb40, 0xfb41, GRUB_BIDI_TYPE_R}, -{0xfb43, 0xfb44, GRUB_BIDI_TYPE_R}, -{0xfb46, 0xfb4f, GRUB_BIDI_TYPE_R}, -{0xfb50, 0xfbb1, GRUB_BIDI_TYPE_AL}, -{0xfbd3, 0xfd3d, GRUB_BIDI_TYPE_AL}, -{0xfd3e, 0xfd3f, GRUB_BIDI_TYPE_ON}, -{0xfd50, 0xfd8f, GRUB_BIDI_TYPE_AL}, -{0xfd92, 0xfdc7, GRUB_BIDI_TYPE_AL}, -{0xfdf0, 0xfdfc, GRUB_BIDI_TYPE_AL}, -{0xfdfd, 0xfdfd, GRUB_BIDI_TYPE_ON}, -{0xfe00, 0xfe0f, GRUB_BIDI_TYPE_NSM}, -{0xfe10, 0xfe19, GRUB_BIDI_TYPE_ON}, -{0xfe20, 0xfe26, GRUB_BIDI_TYPE_NSM}, -{0xfe30, 0xfe4f, GRUB_BIDI_TYPE_ON}, -{0xfe50, 0xfe50, GRUB_BIDI_TYPE_CS}, -{0xfe51, 0xfe51, GRUB_BIDI_TYPE_ON}, -{0xfe52, 0xfe52, GRUB_BIDI_TYPE_CS}, -{0xfe54, 0xfe54, GRUB_BIDI_TYPE_ON}, -{0xfe55, 0xfe55, GRUB_BIDI_TYPE_CS}, -{0xfe56, 0xfe5e, GRUB_BIDI_TYPE_ON}, -{0xfe5f, 0xfe5f, GRUB_BIDI_TYPE_ET}, -{0xfe60, 0xfe61, GRUB_BIDI_TYPE_ON}, -{0xfe62, 0xfe63, GRUB_BIDI_TYPE_ES}, -{0xfe64, 0xfe66, GRUB_BIDI_TYPE_ON}, -{0xfe68, 0xfe68, GRUB_BIDI_TYPE_ON}, -{0xfe69, 0xfe6a, GRUB_BIDI_TYPE_ET}, -{0xfe6b, 0xfe6b, GRUB_BIDI_TYPE_ON}, -{0xfe70, 0xfe74, GRUB_BIDI_TYPE_AL}, -{0xfe76, 0xfefc, GRUB_BIDI_TYPE_AL}, -{0xfeff, 0xfeff, GRUB_BIDI_TYPE_BN}, -{0xff01, 0xff02, GRUB_BIDI_TYPE_ON}, -{0xff03, 0xff05, GRUB_BIDI_TYPE_ET}, -{0xff06, 0xff0a, GRUB_BIDI_TYPE_ON}, -{0xff0b, 0xff0b, GRUB_BIDI_TYPE_ES}, -{0xff0c, 0xff0c, GRUB_BIDI_TYPE_CS}, -{0xff0d, 0xff0d, GRUB_BIDI_TYPE_ES}, -{0xff0e, 0xff0f, GRUB_BIDI_TYPE_CS}, -{0xff10, 0xff19, GRUB_BIDI_TYPE_EN}, -{0xff1a, 0xff1a, GRUB_BIDI_TYPE_CS}, -{0xff1b, 0xff20, GRUB_BIDI_TYPE_ON}, -{0xff3b, 0xff40, GRUB_BIDI_TYPE_ON}, -{0xff5b, 0xff65, GRUB_BIDI_TYPE_ON}, -{0xffe0, 0xffe1, GRUB_BIDI_TYPE_ET}, -{0xffe2, 0xffe4, GRUB_BIDI_TYPE_ON}, -{0xffe5, 0xffe6, GRUB_BIDI_TYPE_ET}, -{0xffe8, 0xffee, GRUB_BIDI_TYPE_ON}, -{0xfff9, 0xfffd, GRUB_BIDI_TYPE_ON}, -{0x10101, 0x10101, GRUB_BIDI_TYPE_ON}, -{0x10140, 0x1018a, GRUB_BIDI_TYPE_ON}, -{0x10190, 0x1019b, GRUB_BIDI_TYPE_ON}, -{0x101fd, 0x101fd, GRUB_BIDI_TYPE_NSM}, -{0x10800, 0x10805, GRUB_BIDI_TYPE_R}, -{0x10808, 0x10808, GRUB_BIDI_TYPE_R}, -{0x1080a, 0x10835, GRUB_BIDI_TYPE_R}, -{0x10837, 0x10838, GRUB_BIDI_TYPE_R}, -{0x1083c, 0x1083c, GRUB_BIDI_TYPE_R}, -{0x1083f, 0x1083f, GRUB_BIDI_TYPE_R}, -{0x10900, 0x10919, GRUB_BIDI_TYPE_R}, -{0x1091f, 0x1091f, GRUB_BIDI_TYPE_ON}, -{0x10920, 0x10939, GRUB_BIDI_TYPE_R}, -{0x1093f, 0x1093f, GRUB_BIDI_TYPE_R}, -{0x10a00, 0x10a00, GRUB_BIDI_TYPE_R}, -{0x10a01, 0x10a03, GRUB_BIDI_TYPE_NSM}, -{0x10a05, 0x10a06, GRUB_BIDI_TYPE_NSM}, -{0x10a0c, 0x10a0f, GRUB_BIDI_TYPE_NSM}, -{0x10a10, 0x10a13, GRUB_BIDI_TYPE_R}, -{0x10a15, 0x10a17, GRUB_BIDI_TYPE_R}, -{0x10a19, 0x10a33, GRUB_BIDI_TYPE_R}, -{0x10a38, 0x10a3a, GRUB_BIDI_TYPE_NSM}, -{0x10a3f, 0x10a3f, GRUB_BIDI_TYPE_NSM}, -{0x10a40, 0x10a47, GRUB_BIDI_TYPE_R}, -{0x10a50, 0x10a58, GRUB_BIDI_TYPE_R}, -{0x1d167, 0x1d169, GRUB_BIDI_TYPE_NSM}, -{0x1d173, 0x1d17a, GRUB_BIDI_TYPE_BN}, -{0x1d17b, 0x1d182, GRUB_BIDI_TYPE_NSM}, -{0x1d185, 0x1d18b, GRUB_BIDI_TYPE_NSM}, -{0x1d1aa, 0x1d1ad, GRUB_BIDI_TYPE_NSM}, -{0x1d200, 0x1d241, GRUB_BIDI_TYPE_ON}, -{0x1d242, 0x1d244, GRUB_BIDI_TYPE_NSM}, -{0x1d245, 0x1d245, GRUB_BIDI_TYPE_ON}, -{0x1d300, 0x1d356, GRUB_BIDI_TYPE_ON}, -{0x1d7ce, 0x1d7ff, GRUB_BIDI_TYPE_EN}, -{0x1f000, 0x1f02b, GRUB_BIDI_TYPE_ON}, -{0x1f030, 0x1f093, GRUB_BIDI_TYPE_ON}, -{0xe0001, 0xe0001, GRUB_BIDI_TYPE_BN}, -{0xe0020, 0xe007f, GRUB_BIDI_TYPE_BN}, -{0xe0100, 0xe01ef, GRUB_BIDI_TYPE_NSM}, -{0, 0, 0}, +struct grub_unicode_compact_range grub_unicode_compact[] = { +{0x0, 0x8, GRUB_BIDI_TYPE_BN, 0}, +{0x9, 0x9, GRUB_BIDI_TYPE_S, 0}, +{0xa, 0xa, GRUB_BIDI_TYPE_B, 0}, +{0xb, 0xb, GRUB_BIDI_TYPE_S, 0}, +{0xc, 0xc, GRUB_BIDI_TYPE_WS, 0}, +{0xd, 0xd, GRUB_BIDI_TYPE_B, 0}, +{0xe, 0x1b, GRUB_BIDI_TYPE_BN, 0}, +{0x1c, 0x1e, GRUB_BIDI_TYPE_B, 0}, +{0x1f, 0x1f, GRUB_BIDI_TYPE_S, 0}, +{0x20, 0x20, GRUB_BIDI_TYPE_WS, 0}, +{0x21, 0x22, GRUB_BIDI_TYPE_ON, 0}, +{0x23, 0x25, GRUB_BIDI_TYPE_ET, 0}, +{0x26, 0x2a, GRUB_BIDI_TYPE_ON, 0}, +{0x2b, 0x2b, GRUB_BIDI_TYPE_ES, 0}, +{0x2c, 0x2c, GRUB_BIDI_TYPE_CS, 0}, +{0x2d, 0x2d, GRUB_BIDI_TYPE_ES, 0}, +{0x2e, 0x2f, GRUB_BIDI_TYPE_CS, 0}, +{0x30, 0x39, GRUB_BIDI_TYPE_EN, 0}, +{0x3a, 0x3a, GRUB_BIDI_TYPE_CS, 0}, +{0x3b, 0x40, GRUB_BIDI_TYPE_ON, 0}, +{0x5b, 0x60, GRUB_BIDI_TYPE_ON, 0}, +{0x7b, 0x7e, GRUB_BIDI_TYPE_ON, 0}, +{0x7f, 0x84, GRUB_BIDI_TYPE_BN, 0}, +{0x85, 0x85, GRUB_BIDI_TYPE_B, 0}, +{0x86, 0x9f, GRUB_BIDI_TYPE_BN, 0}, +{0xa0, 0xa0, GRUB_BIDI_TYPE_CS, 0}, +{0xa1, 0xa1, GRUB_BIDI_TYPE_ON, 0}, +{0xa2, 0xa5, GRUB_BIDI_TYPE_ET, 0}, +{0xa6, 0xa9, GRUB_BIDI_TYPE_ON, 0}, +{0xab, 0xac, GRUB_BIDI_TYPE_ON, 0}, +{0xad, 0xad, GRUB_BIDI_TYPE_BN, 0}, +{0xae, 0xaf, GRUB_BIDI_TYPE_ON, 0}, +{0xb0, 0xb1, GRUB_BIDI_TYPE_ET, 0}, +{0xb2, 0xb3, GRUB_BIDI_TYPE_EN, 0}, +{0xb4, 0xb4, GRUB_BIDI_TYPE_ON, 0}, +{0xb6, 0xb8, GRUB_BIDI_TYPE_ON, 0}, +{0xb9, 0xb9, GRUB_BIDI_TYPE_EN, 0}, +{0xbb, 0xbf, GRUB_BIDI_TYPE_ON, 0}, +{0xd7, 0xd7, GRUB_BIDI_TYPE_ON, 0}, +{0xf7, 0xf7, GRUB_BIDI_TYPE_ON, 0}, +{0x2b9, 0x2ba, GRUB_BIDI_TYPE_ON, 0}, +{0x2c2, 0x2cf, GRUB_BIDI_TYPE_ON, 0}, +{0x2d2, 0x2df, GRUB_BIDI_TYPE_ON, 0}, +{0x2e5, 0x2ed, GRUB_BIDI_TYPE_ON, 0}, +{0x2ef, 0x2ff, GRUB_BIDI_TYPE_ON, 0}, +{0x300, 0x314, GRUB_BIDI_TYPE_NSM, 230}, +{0x315, 0x315, GRUB_BIDI_TYPE_NSM, 232}, +{0x316, 0x319, GRUB_BIDI_TYPE_NSM, 220}, +{0x31a, 0x31a, GRUB_BIDI_TYPE_NSM, 232}, +{0x31b, 0x31b, GRUB_BIDI_TYPE_NSM, 216}, +{0x31c, 0x320, GRUB_BIDI_TYPE_NSM, 220}, +{0x321, 0x322, GRUB_BIDI_TYPE_NSM, 202}, +{0x323, 0x326, GRUB_BIDI_TYPE_NSM, 220}, +{0x327, 0x328, GRUB_BIDI_TYPE_NSM, 202}, +{0x329, 0x333, GRUB_BIDI_TYPE_NSM, 220}, +{0x334, 0x338, GRUB_BIDI_TYPE_NSM, 1}, +{0x339, 0x33c, GRUB_BIDI_TYPE_NSM, 220}, +{0x33d, 0x344, GRUB_BIDI_TYPE_NSM, 230}, +{0x345, 0x345, GRUB_BIDI_TYPE_NSM, 240}, +{0x346, 0x346, GRUB_BIDI_TYPE_NSM, 230}, +{0x347, 0x349, GRUB_BIDI_TYPE_NSM, 220}, +{0x34a, 0x34c, GRUB_BIDI_TYPE_NSM, 230}, +{0x34d, 0x34e, GRUB_BIDI_TYPE_NSM, 220}, +{0x34f, 0x34f, GRUB_BIDI_TYPE_NSM, 255}, +{0x350, 0x352, GRUB_BIDI_TYPE_NSM, 230}, +{0x353, 0x356, GRUB_BIDI_TYPE_NSM, 220}, +{0x357, 0x357, GRUB_BIDI_TYPE_NSM, 230}, +{0x358, 0x358, GRUB_BIDI_TYPE_NSM, 232}, +{0x359, 0x35a, GRUB_BIDI_TYPE_NSM, 220}, +{0x35b, 0x35b, GRUB_BIDI_TYPE_NSM, 230}, +{0x35c, 0x35c, GRUB_BIDI_TYPE_NSM, 233}, +{0x35d, 0x35e, GRUB_BIDI_TYPE_NSM, 234}, +{0x35f, 0x35f, GRUB_BIDI_TYPE_NSM, 233}, +{0x360, 0x361, GRUB_BIDI_TYPE_NSM, 234}, +{0x362, 0x362, GRUB_BIDI_TYPE_NSM, 233}, +{0x363, 0x36f, GRUB_BIDI_TYPE_NSM, 230}, +{0x374, 0x375, GRUB_BIDI_TYPE_ON, 0}, +{0x37e, 0x37e, GRUB_BIDI_TYPE_ON, 0}, +{0x384, 0x385, GRUB_BIDI_TYPE_ON, 0}, +{0x387, 0x387, GRUB_BIDI_TYPE_ON, 0}, +{0x3f6, 0x3f6, GRUB_BIDI_TYPE_ON, 0}, +{0x483, 0x487, GRUB_BIDI_TYPE_NSM, 230}, +{0x488, 0x489, GRUB_BIDI_TYPE_NSM, 253}, +{0x58a, 0x58a, GRUB_BIDI_TYPE_ON, 0}, +{0x591, 0x591, GRUB_BIDI_TYPE_NSM, 220}, +{0x592, 0x595, GRUB_BIDI_TYPE_NSM, 230}, +{0x596, 0x596, GRUB_BIDI_TYPE_NSM, 220}, +{0x597, 0x599, GRUB_BIDI_TYPE_NSM, 230}, +{0x59a, 0x59a, GRUB_BIDI_TYPE_NSM, 222}, +{0x59b, 0x59b, GRUB_BIDI_TYPE_NSM, 220}, +{0x59c, 0x5a1, GRUB_BIDI_TYPE_NSM, 230}, +{0x5a2, 0x5a7, GRUB_BIDI_TYPE_NSM, 220}, +{0x5a8, 0x5a9, GRUB_BIDI_TYPE_NSM, 230}, +{0x5aa, 0x5aa, GRUB_BIDI_TYPE_NSM, 220}, +{0x5ab, 0x5ac, GRUB_BIDI_TYPE_NSM, 230}, +{0x5ad, 0x5ad, GRUB_BIDI_TYPE_NSM, 222}, +{0x5ae, 0x5ae, GRUB_BIDI_TYPE_NSM, 228}, +{0x5af, 0x5af, GRUB_BIDI_TYPE_NSM, 230}, +{0x5b0, 0x5b0, GRUB_BIDI_TYPE_NSM, 10}, +{0x5b1, 0x5b1, GRUB_BIDI_TYPE_NSM, 11}, +{0x5b2, 0x5b2, GRUB_BIDI_TYPE_NSM, 12}, +{0x5b3, 0x5b3, GRUB_BIDI_TYPE_NSM, 13}, +{0x5b4, 0x5b4, GRUB_BIDI_TYPE_NSM, 14}, +{0x5b5, 0x5b5, GRUB_BIDI_TYPE_NSM, 15}, +{0x5b6, 0x5b6, GRUB_BIDI_TYPE_NSM, 16}, +{0x5b7, 0x5b7, GRUB_BIDI_TYPE_NSM, 17}, +{0x5b8, 0x5b8, GRUB_BIDI_TYPE_NSM, 18}, +{0x5b9, 0x5ba, GRUB_BIDI_TYPE_NSM, 19}, +{0x5bb, 0x5bb, GRUB_BIDI_TYPE_NSM, 20}, +{0x5bc, 0x5bc, GRUB_BIDI_TYPE_NSM, 21}, +{0x5bd, 0x5bd, GRUB_BIDI_TYPE_NSM, 22}, +{0x5be, 0x5be, GRUB_BIDI_TYPE_R, 0}, +{0x5bf, 0x5bf, GRUB_BIDI_TYPE_NSM, 23}, +{0x5c0, 0x5c0, GRUB_BIDI_TYPE_R, 0}, +{0x5c1, 0x5c1, GRUB_BIDI_TYPE_NSM, 24}, +{0x5c2, 0x5c2, GRUB_BIDI_TYPE_NSM, 25}, +{0x5c3, 0x5c3, GRUB_BIDI_TYPE_R, 0}, +{0x5c4, 0x5c4, GRUB_BIDI_TYPE_NSM, 230}, +{0x5c5, 0x5c5, GRUB_BIDI_TYPE_NSM, 220}, +{0x5c6, 0x5c6, GRUB_BIDI_TYPE_R, 0}, +{0x5c7, 0x5c7, GRUB_BIDI_TYPE_NSM, 18}, +{0x5d0, 0x5ea, GRUB_BIDI_TYPE_R, 0}, +{0x5f0, 0x5f4, GRUB_BIDI_TYPE_R, 0}, +{0x600, 0x603, GRUB_BIDI_TYPE_AN, 0}, +{0x606, 0x607, GRUB_BIDI_TYPE_ON, 0}, +{0x608, 0x608, GRUB_BIDI_TYPE_AL, 0}, +{0x609, 0x60a, GRUB_BIDI_TYPE_ET, 0}, +{0x60b, 0x60b, GRUB_BIDI_TYPE_AL, 0}, +{0x60c, 0x60c, GRUB_BIDI_TYPE_CS, 0}, +{0x60d, 0x60d, GRUB_BIDI_TYPE_AL, 0}, +{0x60e, 0x60f, GRUB_BIDI_TYPE_ON, 0}, +{0x610, 0x617, GRUB_BIDI_TYPE_NSM, 230}, +{0x618, 0x618, GRUB_BIDI_TYPE_NSM, 30}, +{0x619, 0x619, GRUB_BIDI_TYPE_NSM, 31}, +{0x61a, 0x61a, GRUB_BIDI_TYPE_NSM, 32}, +{0x61b, 0x61b, GRUB_BIDI_TYPE_AL, 0}, +{0x61e, 0x61f, GRUB_BIDI_TYPE_AL, 0}, +{0x621, 0x64a, GRUB_BIDI_TYPE_AL, 0}, +{0x64b, 0x64b, GRUB_BIDI_TYPE_NSM, 27}, +{0x64c, 0x64c, GRUB_BIDI_TYPE_NSM, 28}, +{0x64d, 0x64d, GRUB_BIDI_TYPE_NSM, 29}, +{0x64e, 0x64e, GRUB_BIDI_TYPE_NSM, 30}, +{0x64f, 0x64f, GRUB_BIDI_TYPE_NSM, 31}, +{0x650, 0x650, GRUB_BIDI_TYPE_NSM, 32}, +{0x651, 0x651, GRUB_BIDI_TYPE_NSM, 33}, +{0x652, 0x652, GRUB_BIDI_TYPE_NSM, 34}, +{0x653, 0x654, GRUB_BIDI_TYPE_NSM, 230}, +{0x655, 0x656, GRUB_BIDI_TYPE_NSM, 220}, +{0x657, 0x65b, GRUB_BIDI_TYPE_NSM, 230}, +{0x65c, 0x65c, GRUB_BIDI_TYPE_NSM, 220}, +{0x65d, 0x65e, GRUB_BIDI_TYPE_NSM, 230}, +{0x660, 0x669, GRUB_BIDI_TYPE_AN, 0}, +{0x66a, 0x66a, GRUB_BIDI_TYPE_ET, 0}, +{0x66b, 0x66c, GRUB_BIDI_TYPE_AN, 0}, +{0x66d, 0x66f, GRUB_BIDI_TYPE_AL, 0}, +{0x670, 0x670, GRUB_BIDI_TYPE_NSM, 35}, +{0x671, 0x6d5, GRUB_BIDI_TYPE_AL, 0}, +{0x6d6, 0x6dc, GRUB_BIDI_TYPE_NSM, 230}, +{0x6dd, 0x6dd, GRUB_BIDI_TYPE_AN, 0}, +{0x6de, 0x6de, GRUB_BIDI_TYPE_NSM, 253}, +{0x6df, 0x6e2, GRUB_BIDI_TYPE_NSM, 230}, +{0x6e3, 0x6e3, GRUB_BIDI_TYPE_NSM, 220}, +{0x6e4, 0x6e4, GRUB_BIDI_TYPE_NSM, 230}, +{0x6e5, 0x6e6, GRUB_BIDI_TYPE_AL, 0}, +{0x6e7, 0x6e8, GRUB_BIDI_TYPE_NSM, 230}, +{0x6e9, 0x6e9, GRUB_BIDI_TYPE_ON, 0}, +{0x6ea, 0x6ea, GRUB_BIDI_TYPE_NSM, 220}, +{0x6eb, 0x6ec, GRUB_BIDI_TYPE_NSM, 230}, +{0x6ed, 0x6ed, GRUB_BIDI_TYPE_NSM, 220}, +{0x6ee, 0x6ef, GRUB_BIDI_TYPE_AL, 0}, +{0x6f0, 0x6f9, GRUB_BIDI_TYPE_EN, 0}, +{0x6fa, 0x70d, GRUB_BIDI_TYPE_AL, 0}, +{0x70f, 0x70f, GRUB_BIDI_TYPE_BN, 0}, +{0x710, 0x710, GRUB_BIDI_TYPE_AL, 0}, +{0x711, 0x711, GRUB_BIDI_TYPE_NSM, 36}, +{0x712, 0x72f, GRUB_BIDI_TYPE_AL, 0}, +{0x730, 0x730, GRUB_BIDI_TYPE_NSM, 230}, +{0x731, 0x731, GRUB_BIDI_TYPE_NSM, 220}, +{0x732, 0x733, GRUB_BIDI_TYPE_NSM, 230}, +{0x734, 0x734, GRUB_BIDI_TYPE_NSM, 220}, +{0x735, 0x736, GRUB_BIDI_TYPE_NSM, 230}, +{0x737, 0x739, GRUB_BIDI_TYPE_NSM, 220}, +{0x73a, 0x73a, GRUB_BIDI_TYPE_NSM, 230}, +{0x73b, 0x73c, GRUB_BIDI_TYPE_NSM, 220}, +{0x73d, 0x73d, GRUB_BIDI_TYPE_NSM, 230}, +{0x73e, 0x73e, GRUB_BIDI_TYPE_NSM, 220}, +{0x73f, 0x741, GRUB_BIDI_TYPE_NSM, 230}, +{0x742, 0x742, GRUB_BIDI_TYPE_NSM, 220}, +{0x743, 0x743, GRUB_BIDI_TYPE_NSM, 230}, +{0x744, 0x744, GRUB_BIDI_TYPE_NSM, 220}, +{0x745, 0x745, GRUB_BIDI_TYPE_NSM, 230}, +{0x746, 0x746, GRUB_BIDI_TYPE_NSM, 220}, +{0x747, 0x747, GRUB_BIDI_TYPE_NSM, 230}, +{0x748, 0x748, GRUB_BIDI_TYPE_NSM, 220}, +{0x749, 0x74a, GRUB_BIDI_TYPE_NSM, 230}, +{0x74d, 0x7a5, GRUB_BIDI_TYPE_AL, 0}, +{0x7a6, 0x7b0, GRUB_BIDI_TYPE_NSM, 255}, +{0x7b1, 0x7b1, GRUB_BIDI_TYPE_AL, 0}, +{0x7c0, 0x7ea, GRUB_BIDI_TYPE_R, 0}, +{0x7eb, 0x7f1, GRUB_BIDI_TYPE_NSM, 230}, +{0x7f2, 0x7f2, GRUB_BIDI_TYPE_NSM, 220}, +{0x7f3, 0x7f3, GRUB_BIDI_TYPE_NSM, 230}, +{0x7f4, 0x7f5, GRUB_BIDI_TYPE_R, 0}, +{0x7f6, 0x7f9, GRUB_BIDI_TYPE_ON, 0}, +{0x7fa, 0x7fa, GRUB_BIDI_TYPE_R, 0}, +{0x901, 0x902, GRUB_BIDI_TYPE_NSM, 255}, +{0x903, 0x903, GRUB_BIDI_TYPE_L, 254}, +{0x93c, 0x93c, GRUB_BIDI_TYPE_NSM, 7}, +{0x93e, 0x940, GRUB_BIDI_TYPE_L, 254}, +{0x941, 0x948, GRUB_BIDI_TYPE_NSM, 255}, +{0x949, 0x94c, GRUB_BIDI_TYPE_L, 254}, +{0x94d, 0x94d, GRUB_BIDI_TYPE_NSM, 9}, +{0x951, 0x951, GRUB_BIDI_TYPE_NSM, 230}, +{0x952, 0x952, GRUB_BIDI_TYPE_NSM, 220}, +{0x953, 0x954, GRUB_BIDI_TYPE_NSM, 230}, +{0x962, 0x963, GRUB_BIDI_TYPE_NSM, 255}, +{0x981, 0x981, GRUB_BIDI_TYPE_NSM, 255}, +{0x982, 0x983, GRUB_BIDI_TYPE_L, 254}, +{0x9bc, 0x9bc, GRUB_BIDI_TYPE_NSM, 7}, +{0x9be, 0x9c0, GRUB_BIDI_TYPE_L, 254}, +{0x9c1, 0x9c4, GRUB_BIDI_TYPE_NSM, 255}, +{0x9c7, 0x9c8, GRUB_BIDI_TYPE_L, 254}, +{0x9cb, 0x9cc, GRUB_BIDI_TYPE_L, 254}, +{0x9cd, 0x9cd, GRUB_BIDI_TYPE_NSM, 9}, +{0x9d7, 0x9d7, GRUB_BIDI_TYPE_L, 254}, +{0x9e2, 0x9e3, GRUB_BIDI_TYPE_NSM, 255}, +{0x9f2, 0x9f3, GRUB_BIDI_TYPE_ET, 0}, +{0xa01, 0xa02, GRUB_BIDI_TYPE_NSM, 255}, +{0xa03, 0xa03, GRUB_BIDI_TYPE_L, 254}, +{0xa3c, 0xa3c, GRUB_BIDI_TYPE_NSM, 7}, +{0xa3e, 0xa40, GRUB_BIDI_TYPE_L, 254}, +{0xa41, 0xa42, GRUB_BIDI_TYPE_NSM, 255}, +{0xa47, 0xa48, GRUB_BIDI_TYPE_NSM, 255}, +{0xa4b, 0xa4c, GRUB_BIDI_TYPE_NSM, 255}, +{0xa4d, 0xa4d, GRUB_BIDI_TYPE_NSM, 9}, +{0xa51, 0xa51, GRUB_BIDI_TYPE_NSM, 255}, +{0xa70, 0xa71, GRUB_BIDI_TYPE_NSM, 255}, +{0xa75, 0xa75, GRUB_BIDI_TYPE_NSM, 255}, +{0xa81, 0xa82, GRUB_BIDI_TYPE_NSM, 255}, +{0xa83, 0xa83, GRUB_BIDI_TYPE_L, 254}, +{0xabc, 0xabc, GRUB_BIDI_TYPE_NSM, 7}, +{0xabe, 0xac0, GRUB_BIDI_TYPE_L, 254}, +{0xac1, 0xac5, GRUB_BIDI_TYPE_NSM, 255}, +{0xac7, 0xac8, GRUB_BIDI_TYPE_NSM, 255}, +{0xac9, 0xac9, GRUB_BIDI_TYPE_L, 254}, +{0xacb, 0xacc, GRUB_BIDI_TYPE_L, 254}, +{0xacd, 0xacd, GRUB_BIDI_TYPE_NSM, 9}, +{0xae2, 0xae3, GRUB_BIDI_TYPE_NSM, 255}, +{0xaf1, 0xaf1, GRUB_BIDI_TYPE_ET, 0}, +{0xb01, 0xb01, GRUB_BIDI_TYPE_NSM, 255}, +{0xb02, 0xb03, GRUB_BIDI_TYPE_L, 254}, +{0xb3c, 0xb3c, GRUB_BIDI_TYPE_NSM, 7}, +{0xb3e, 0xb3e, GRUB_BIDI_TYPE_L, 254}, +{0xb3f, 0xb3f, GRUB_BIDI_TYPE_NSM, 255}, +{0xb40, 0xb40, GRUB_BIDI_TYPE_L, 254}, +{0xb41, 0xb44, GRUB_BIDI_TYPE_NSM, 255}, +{0xb47, 0xb48, GRUB_BIDI_TYPE_L, 254}, +{0xb4b, 0xb4c, GRUB_BIDI_TYPE_L, 254}, +{0xb4d, 0xb4d, GRUB_BIDI_TYPE_NSM, 9}, +{0xb56, 0xb56, GRUB_BIDI_TYPE_NSM, 255}, +{0xb57, 0xb57, GRUB_BIDI_TYPE_L, 254}, +{0xb62, 0xb63, GRUB_BIDI_TYPE_NSM, 255}, +{0xb82, 0xb82, GRUB_BIDI_TYPE_NSM, 255}, +{0xbbe, 0xbbf, GRUB_BIDI_TYPE_L, 254}, +{0xbc0, 0xbc0, GRUB_BIDI_TYPE_NSM, 255}, +{0xbc1, 0xbc2, GRUB_BIDI_TYPE_L, 254}, +{0xbc6, 0xbc8, GRUB_BIDI_TYPE_L, 254}, +{0xbca, 0xbcc, GRUB_BIDI_TYPE_L, 254}, +{0xbcd, 0xbcd, GRUB_BIDI_TYPE_NSM, 9}, +{0xbd7, 0xbd7, GRUB_BIDI_TYPE_L, 254}, +{0xbf3, 0xbf8, GRUB_BIDI_TYPE_ON, 0}, +{0xbf9, 0xbf9, GRUB_BIDI_TYPE_ET, 0}, +{0xbfa, 0xbfa, GRUB_BIDI_TYPE_ON, 0}, +{0xc01, 0xc03, GRUB_BIDI_TYPE_L, 254}, +{0xc3e, 0xc40, GRUB_BIDI_TYPE_NSM, 255}, +{0xc41, 0xc44, GRUB_BIDI_TYPE_L, 254}, +{0xc46, 0xc48, GRUB_BIDI_TYPE_NSM, 255}, +{0xc4a, 0xc4c, GRUB_BIDI_TYPE_NSM, 255}, +{0xc4d, 0xc4d, GRUB_BIDI_TYPE_NSM, 9}, +{0xc55, 0xc55, GRUB_BIDI_TYPE_NSM, 84}, +{0xc56, 0xc56, GRUB_BIDI_TYPE_NSM, 91}, +{0xc62, 0xc63, GRUB_BIDI_TYPE_NSM, 255}, +{0xc78, 0xc7e, GRUB_BIDI_TYPE_ON, 0}, +{0xc82, 0xc83, GRUB_BIDI_TYPE_L, 254}, +{0xcbc, 0xcbc, GRUB_BIDI_TYPE_NSM, 7}, +{0xcbe, 0xcbe, GRUB_BIDI_TYPE_L, 254}, +{0xcbf, 0xcbf, GRUB_BIDI_TYPE_L, 255}, +{0xcc0, 0xcc4, GRUB_BIDI_TYPE_L, 254}, +{0xcc6, 0xcc6, GRUB_BIDI_TYPE_L, 255}, +{0xcc7, 0xcc8, GRUB_BIDI_TYPE_L, 254}, +{0xcca, 0xccb, GRUB_BIDI_TYPE_L, 254}, +{0xccc, 0xccc, GRUB_BIDI_TYPE_NSM, 255}, +{0xccd, 0xccd, GRUB_BIDI_TYPE_NSM, 9}, +{0xcd5, 0xcd6, GRUB_BIDI_TYPE_L, 254}, +{0xce2, 0xce3, GRUB_BIDI_TYPE_NSM, 255}, +{0xcf1, 0xcf2, GRUB_BIDI_TYPE_ON, 0}, +{0xd02, 0xd03, GRUB_BIDI_TYPE_L, 254}, +{0xd3e, 0xd40, GRUB_BIDI_TYPE_L, 254}, +{0xd41, 0xd44, GRUB_BIDI_TYPE_NSM, 255}, +{0xd46, 0xd48, GRUB_BIDI_TYPE_L, 254}, +{0xd4a, 0xd4c, GRUB_BIDI_TYPE_L, 254}, +{0xd4d, 0xd4d, GRUB_BIDI_TYPE_NSM, 9}, +{0xd57, 0xd57, GRUB_BIDI_TYPE_L, 254}, +{0xd62, 0xd63, GRUB_BIDI_TYPE_NSM, 255}, +{0xd82, 0xd83, GRUB_BIDI_TYPE_L, 254}, +{0xdca, 0xdca, GRUB_BIDI_TYPE_NSM, 9}, +{0xdcf, 0xdd1, GRUB_BIDI_TYPE_L, 254}, +{0xdd2, 0xdd4, GRUB_BIDI_TYPE_NSM, 255}, +{0xdd6, 0xdd6, GRUB_BIDI_TYPE_NSM, 255}, +{0xdd8, 0xddf, GRUB_BIDI_TYPE_L, 254}, +{0xdf2, 0xdf3, GRUB_BIDI_TYPE_L, 254}, +{0xe31, 0xe31, GRUB_BIDI_TYPE_NSM, 255}, +{0xe34, 0xe37, GRUB_BIDI_TYPE_NSM, 255}, +{0xe38, 0xe39, GRUB_BIDI_TYPE_NSM, 103}, +{0xe3a, 0xe3a, GRUB_BIDI_TYPE_NSM, 9}, +{0xe3f, 0xe3f, GRUB_BIDI_TYPE_ET, 0}, +{0xe47, 0xe47, GRUB_BIDI_TYPE_NSM, 255}, +{0xe48, 0xe4b, GRUB_BIDI_TYPE_NSM, 107}, +{0xe4c, 0xe4e, GRUB_BIDI_TYPE_NSM, 255}, +{0xeb1, 0xeb1, GRUB_BIDI_TYPE_NSM, 255}, +{0xeb4, 0xeb7, GRUB_BIDI_TYPE_NSM, 255}, +{0xeb8, 0xeb9, GRUB_BIDI_TYPE_NSM, 118}, +{0xebb, 0xebc, GRUB_BIDI_TYPE_NSM, 255}, +{0xec8, 0xecb, GRUB_BIDI_TYPE_NSM, 122}, +{0xecc, 0xecd, GRUB_BIDI_TYPE_NSM, 255}, +{0xf18, 0xf19, GRUB_BIDI_TYPE_NSM, 220}, +{0xf35, 0xf35, GRUB_BIDI_TYPE_NSM, 220}, +{0xf37, 0xf37, GRUB_BIDI_TYPE_NSM, 220}, +{0xf39, 0xf39, GRUB_BIDI_TYPE_NSM, 216}, +{0xf3a, 0xf3d, GRUB_BIDI_TYPE_ON, 0}, +{0xf3e, 0xf3f, GRUB_BIDI_TYPE_L, 254}, +{0xf71, 0xf71, GRUB_BIDI_TYPE_NSM, 129}, +{0xf72, 0xf72, GRUB_BIDI_TYPE_NSM, 130}, +{0xf73, 0xf73, GRUB_BIDI_TYPE_NSM, 255}, +{0xf74, 0xf74, GRUB_BIDI_TYPE_NSM, 132}, +{0xf75, 0xf79, GRUB_BIDI_TYPE_NSM, 255}, +{0xf7a, 0xf7d, GRUB_BIDI_TYPE_NSM, 130}, +{0xf7e, 0xf7e, GRUB_BIDI_TYPE_NSM, 255}, +{0xf7f, 0xf7f, GRUB_BIDI_TYPE_L, 254}, +{0xf80, 0xf80, GRUB_BIDI_TYPE_NSM, 130}, +{0xf81, 0xf81, GRUB_BIDI_TYPE_NSM, 255}, +{0xf82, 0xf83, GRUB_BIDI_TYPE_NSM, 230}, +{0xf84, 0xf84, GRUB_BIDI_TYPE_NSM, 9}, +{0xf86, 0xf87, GRUB_BIDI_TYPE_NSM, 230}, +{0xf90, 0xf97, GRUB_BIDI_TYPE_NSM, 255}, +{0xf99, 0xfbc, GRUB_BIDI_TYPE_NSM, 255}, +{0xfc6, 0xfc6, GRUB_BIDI_TYPE_NSM, 220}, +{0x102b, 0x102c, GRUB_BIDI_TYPE_L, 254}, +{0x102d, 0x1030, GRUB_BIDI_TYPE_NSM, 255}, +{0x1031, 0x1031, GRUB_BIDI_TYPE_L, 254}, +{0x1032, 0x1036, GRUB_BIDI_TYPE_NSM, 255}, +{0x1037, 0x1037, GRUB_BIDI_TYPE_NSM, 7}, +{0x1038, 0x1038, GRUB_BIDI_TYPE_L, 254}, +{0x1039, 0x103a, GRUB_BIDI_TYPE_NSM, 9}, +{0x103b, 0x103c, GRUB_BIDI_TYPE_L, 254}, +{0x103d, 0x103e, GRUB_BIDI_TYPE_NSM, 255}, +{0x1056, 0x1057, GRUB_BIDI_TYPE_L, 254}, +{0x1058, 0x1059, GRUB_BIDI_TYPE_NSM, 255}, +{0x105e, 0x1060, GRUB_BIDI_TYPE_NSM, 255}, +{0x1062, 0x1064, GRUB_BIDI_TYPE_L, 254}, +{0x1067, 0x106d, GRUB_BIDI_TYPE_L, 254}, +{0x1071, 0x1074, GRUB_BIDI_TYPE_NSM, 255}, +{0x1082, 0x1082, GRUB_BIDI_TYPE_NSM, 255}, +{0x1083, 0x1084, GRUB_BIDI_TYPE_L, 254}, +{0x1085, 0x1086, GRUB_BIDI_TYPE_NSM, 255}, +{0x1087, 0x108c, GRUB_BIDI_TYPE_L, 254}, +{0x108d, 0x108d, GRUB_BIDI_TYPE_NSM, 220}, +{0x108f, 0x108f, GRUB_BIDI_TYPE_L, 254}, +{0x135f, 0x135f, GRUB_BIDI_TYPE_NSM, 230}, +{0x1390, 0x1399, GRUB_BIDI_TYPE_ON, 0}, +{0x1680, 0x1680, GRUB_BIDI_TYPE_WS, 0}, +{0x169b, 0x169c, GRUB_BIDI_TYPE_ON, 0}, +{0x1712, 0x1713, GRUB_BIDI_TYPE_NSM, 255}, +{0x1714, 0x1714, GRUB_BIDI_TYPE_NSM, 9}, +{0x1732, 0x1733, GRUB_BIDI_TYPE_NSM, 255}, +{0x1734, 0x1734, GRUB_BIDI_TYPE_NSM, 9}, +{0x1752, 0x1753, GRUB_BIDI_TYPE_NSM, 255}, +{0x1772, 0x1773, GRUB_BIDI_TYPE_NSM, 255}, +{0x17b6, 0x17b6, GRUB_BIDI_TYPE_L, 254}, +{0x17b7, 0x17bd, GRUB_BIDI_TYPE_NSM, 255}, +{0x17be, 0x17c5, GRUB_BIDI_TYPE_L, 254}, +{0x17c6, 0x17c6, GRUB_BIDI_TYPE_NSM, 255}, +{0x17c7, 0x17c8, GRUB_BIDI_TYPE_L, 254}, +{0x17c9, 0x17d1, GRUB_BIDI_TYPE_NSM, 255}, +{0x17d2, 0x17d2, GRUB_BIDI_TYPE_NSM, 9}, +{0x17d3, 0x17d3, GRUB_BIDI_TYPE_NSM, 255}, +{0x17db, 0x17db, GRUB_BIDI_TYPE_ET, 0}, +{0x17dd, 0x17dd, GRUB_BIDI_TYPE_NSM, 230}, +{0x17f0, 0x17f9, GRUB_BIDI_TYPE_ON, 0}, +{0x1800, 0x180a, GRUB_BIDI_TYPE_ON, 0}, +{0x180b, 0x180d, GRUB_BIDI_TYPE_NSM, 255}, +{0x180e, 0x180e, GRUB_BIDI_TYPE_WS, 0}, +{0x18a9, 0x18a9, GRUB_BIDI_TYPE_NSM, 228}, +{0x1920, 0x1922, GRUB_BIDI_TYPE_NSM, 255}, +{0x1923, 0x1926, GRUB_BIDI_TYPE_L, 254}, +{0x1927, 0x1928, GRUB_BIDI_TYPE_NSM, 255}, +{0x1929, 0x192b, GRUB_BIDI_TYPE_L, 254}, +{0x1930, 0x1931, GRUB_BIDI_TYPE_L, 254}, +{0x1932, 0x1932, GRUB_BIDI_TYPE_NSM, 255}, +{0x1933, 0x1938, GRUB_BIDI_TYPE_L, 254}, +{0x1939, 0x1939, GRUB_BIDI_TYPE_NSM, 222}, +{0x193a, 0x193a, GRUB_BIDI_TYPE_NSM, 230}, +{0x193b, 0x193b, GRUB_BIDI_TYPE_NSM, 220}, +{0x1940, 0x1940, GRUB_BIDI_TYPE_ON, 0}, +{0x1944, 0x1945, GRUB_BIDI_TYPE_ON, 0}, +{0x19b0, 0x19c0, GRUB_BIDI_TYPE_L, 254}, +{0x19c8, 0x19c9, GRUB_BIDI_TYPE_L, 254}, +{0x19de, 0x19ff, GRUB_BIDI_TYPE_ON, 0}, +{0x1a17, 0x1a17, GRUB_BIDI_TYPE_NSM, 230}, +{0x1a18, 0x1a18, GRUB_BIDI_TYPE_NSM, 220}, +{0x1a19, 0x1a1b, GRUB_BIDI_TYPE_L, 254}, +{0x1b00, 0x1b03, GRUB_BIDI_TYPE_NSM, 255}, +{0x1b04, 0x1b04, GRUB_BIDI_TYPE_L, 254}, +{0x1b34, 0x1b34, GRUB_BIDI_TYPE_NSM, 7}, +{0x1b35, 0x1b35, GRUB_BIDI_TYPE_L, 254}, +{0x1b36, 0x1b3a, GRUB_BIDI_TYPE_NSM, 255}, +{0x1b3b, 0x1b3b, GRUB_BIDI_TYPE_L, 254}, +{0x1b3c, 0x1b3c, GRUB_BIDI_TYPE_NSM, 255}, +{0x1b3d, 0x1b41, GRUB_BIDI_TYPE_L, 254}, +{0x1b42, 0x1b42, GRUB_BIDI_TYPE_NSM, 255}, +{0x1b43, 0x1b43, GRUB_BIDI_TYPE_L, 254}, +{0x1b44, 0x1b44, GRUB_BIDI_TYPE_L, 9}, +{0x1b6b, 0x1b6b, GRUB_BIDI_TYPE_NSM, 230}, +{0x1b6c, 0x1b6c, GRUB_BIDI_TYPE_NSM, 220}, +{0x1b6d, 0x1b73, GRUB_BIDI_TYPE_NSM, 230}, +{0x1b80, 0x1b81, GRUB_BIDI_TYPE_NSM, 255}, +{0x1b82, 0x1b82, GRUB_BIDI_TYPE_L, 254}, +{0x1ba1, 0x1ba1, GRUB_BIDI_TYPE_L, 254}, +{0x1ba2, 0x1ba5, GRUB_BIDI_TYPE_NSM, 255}, +{0x1ba6, 0x1ba7, GRUB_BIDI_TYPE_L, 254}, +{0x1ba8, 0x1ba9, GRUB_BIDI_TYPE_NSM, 255}, +{0x1baa, 0x1baa, GRUB_BIDI_TYPE_L, 9}, +{0x1c24, 0x1c2b, GRUB_BIDI_TYPE_L, 254}, +{0x1c2c, 0x1c33, GRUB_BIDI_TYPE_NSM, 255}, +{0x1c34, 0x1c35, GRUB_BIDI_TYPE_L, 254}, +{0x1c36, 0x1c36, GRUB_BIDI_TYPE_NSM, 255}, +{0x1c37, 0x1c37, GRUB_BIDI_TYPE_NSM, 7}, +{0x1dc0, 0x1dc1, GRUB_BIDI_TYPE_NSM, 230}, +{0x1dc2, 0x1dc2, GRUB_BIDI_TYPE_NSM, 220}, +{0x1dc3, 0x1dc9, GRUB_BIDI_TYPE_NSM, 230}, +{0x1dca, 0x1dca, GRUB_BIDI_TYPE_NSM, 220}, +{0x1dcb, 0x1dcc, GRUB_BIDI_TYPE_NSM, 230}, +{0x1dcd, 0x1dcd, GRUB_BIDI_TYPE_NSM, 234}, +{0x1dce, 0x1dce, GRUB_BIDI_TYPE_NSM, 214}, +{0x1dcf, 0x1dcf, GRUB_BIDI_TYPE_NSM, 220}, +{0x1dd0, 0x1dd0, GRUB_BIDI_TYPE_NSM, 202}, +{0x1dd1, 0x1de6, GRUB_BIDI_TYPE_NSM, 230}, +{0x1dfe, 0x1dfe, GRUB_BIDI_TYPE_NSM, 230}, +{0x1dff, 0x1dff, GRUB_BIDI_TYPE_NSM, 220}, +{0x1fbd, 0x1fbd, GRUB_BIDI_TYPE_ON, 0}, +{0x1fbf, 0x1fc1, GRUB_BIDI_TYPE_ON, 0}, +{0x1fcd, 0x1fcf, GRUB_BIDI_TYPE_ON, 0}, +{0x1fdd, 0x1fdf, GRUB_BIDI_TYPE_ON, 0}, +{0x1fed, 0x1fef, GRUB_BIDI_TYPE_ON, 0}, +{0x1ffd, 0x1ffe, GRUB_BIDI_TYPE_ON, 0}, +{0x2000, 0x200a, GRUB_BIDI_TYPE_WS, 0}, +{0x200b, 0x200d, GRUB_BIDI_TYPE_BN, 0}, +{0x200f, 0x200f, GRUB_BIDI_TYPE_R, 0}, +{0x2010, 0x2027, GRUB_BIDI_TYPE_ON, 0}, +{0x2028, 0x2028, GRUB_BIDI_TYPE_WS, 0}, +{0x2029, 0x2029, GRUB_BIDI_TYPE_B, 0}, +{0x202a, 0x202a, GRUB_BIDI_TYPE_LRE, 0}, +{0x202b, 0x202b, GRUB_BIDI_TYPE_RLE, 0}, +{0x202c, 0x202c, GRUB_BIDI_TYPE_PDF, 0}, +{0x202d, 0x202d, GRUB_BIDI_TYPE_LRO, 0}, +{0x202e, 0x202e, GRUB_BIDI_TYPE_RLO, 0}, +{0x202f, 0x202f, GRUB_BIDI_TYPE_CS, 0}, +{0x2030, 0x2034, GRUB_BIDI_TYPE_ET, 0}, +{0x2035, 0x2043, GRUB_BIDI_TYPE_ON, 0}, +{0x2044, 0x2044, GRUB_BIDI_TYPE_CS, 0}, +{0x2045, 0x205e, GRUB_BIDI_TYPE_ON, 0}, +{0x205f, 0x205f, GRUB_BIDI_TYPE_WS, 0}, +{0x2060, 0x2064, GRUB_BIDI_TYPE_BN, 0}, +{0x206a, 0x206f, GRUB_BIDI_TYPE_BN, 0}, +{0x2070, 0x2070, GRUB_BIDI_TYPE_EN, 0}, +{0x2074, 0x2079, GRUB_BIDI_TYPE_EN, 0}, +{0x207a, 0x207b, GRUB_BIDI_TYPE_ES, 0}, +{0x207c, 0x207e, GRUB_BIDI_TYPE_ON, 0}, +{0x2080, 0x2089, GRUB_BIDI_TYPE_EN, 0}, +{0x208a, 0x208b, GRUB_BIDI_TYPE_ES, 0}, +{0x208c, 0x208e, GRUB_BIDI_TYPE_ON, 0}, +{0x20a0, 0x20b5, GRUB_BIDI_TYPE_ET, 0}, +{0x20d0, 0x20d1, GRUB_BIDI_TYPE_NSM, 230}, +{0x20d2, 0x20d3, GRUB_BIDI_TYPE_NSM, 1}, +{0x20d4, 0x20d7, GRUB_BIDI_TYPE_NSM, 230}, +{0x20d8, 0x20da, GRUB_BIDI_TYPE_NSM, 1}, +{0x20db, 0x20dc, GRUB_BIDI_TYPE_NSM, 230}, +{0x20dd, 0x20e0, GRUB_BIDI_TYPE_NSM, 253}, +{0x20e1, 0x20e1, GRUB_BIDI_TYPE_NSM, 230}, +{0x20e2, 0x20e4, GRUB_BIDI_TYPE_NSM, 253}, +{0x20e5, 0x20e6, GRUB_BIDI_TYPE_NSM, 1}, +{0x20e7, 0x20e7, GRUB_BIDI_TYPE_NSM, 230}, +{0x20e8, 0x20e8, GRUB_BIDI_TYPE_NSM, 220}, +{0x20e9, 0x20e9, GRUB_BIDI_TYPE_NSM, 230}, +{0x20ea, 0x20eb, GRUB_BIDI_TYPE_NSM, 1}, +{0x20ec, 0x20ef, GRUB_BIDI_TYPE_NSM, 220}, +{0x20f0, 0x20f0, GRUB_BIDI_TYPE_NSM, 230}, +{0x2100, 0x2101, GRUB_BIDI_TYPE_ON, 0}, +{0x2103, 0x2106, GRUB_BIDI_TYPE_ON, 0}, +{0x2108, 0x2109, GRUB_BIDI_TYPE_ON, 0}, +{0x2114, 0x2114, GRUB_BIDI_TYPE_ON, 0}, +{0x2116, 0x2118, GRUB_BIDI_TYPE_ON, 0}, +{0x211e, 0x2123, GRUB_BIDI_TYPE_ON, 0}, +{0x2125, 0x2125, GRUB_BIDI_TYPE_ON, 0}, +{0x2127, 0x2127, GRUB_BIDI_TYPE_ON, 0}, +{0x2129, 0x2129, GRUB_BIDI_TYPE_ON, 0}, +{0x212e, 0x212e, GRUB_BIDI_TYPE_ET, 0}, +{0x213a, 0x213b, GRUB_BIDI_TYPE_ON, 0}, +{0x2140, 0x2144, GRUB_BIDI_TYPE_ON, 0}, +{0x214a, 0x214d, GRUB_BIDI_TYPE_ON, 0}, +{0x2153, 0x215f, GRUB_BIDI_TYPE_ON, 0}, +{0x2190, 0x2211, GRUB_BIDI_TYPE_ON, 0}, +{0x2212, 0x2212, GRUB_BIDI_TYPE_ES, 0}, +{0x2213, 0x2213, GRUB_BIDI_TYPE_ET, 0}, +{0x2214, 0x2335, GRUB_BIDI_TYPE_ON, 0}, +{0x237b, 0x2394, GRUB_BIDI_TYPE_ON, 0}, +{0x2396, 0x23e7, GRUB_BIDI_TYPE_ON, 0}, +{0x2400, 0x2426, GRUB_BIDI_TYPE_ON, 0}, +{0x2440, 0x244a, GRUB_BIDI_TYPE_ON, 0}, +{0x2460, 0x2487, GRUB_BIDI_TYPE_ON, 0}, +{0x2488, 0x249b, GRUB_BIDI_TYPE_EN, 0}, +{0x24ea, 0x269d, GRUB_BIDI_TYPE_ON, 0}, +{0x26a0, 0x26ab, GRUB_BIDI_TYPE_ON, 0}, +{0x26ad, 0x26bc, GRUB_BIDI_TYPE_ON, 0}, +{0x26c0, 0x26c3, GRUB_BIDI_TYPE_ON, 0}, +{0x2701, 0x2704, GRUB_BIDI_TYPE_ON, 0}, +{0x2706, 0x2709, GRUB_BIDI_TYPE_ON, 0}, +{0x270c, 0x2727, GRUB_BIDI_TYPE_ON, 0}, +{0x2729, 0x274b, GRUB_BIDI_TYPE_ON, 0}, +{0x274d, 0x274d, GRUB_BIDI_TYPE_ON, 0}, +{0x274f, 0x2752, GRUB_BIDI_TYPE_ON, 0}, +{0x2756, 0x2756, GRUB_BIDI_TYPE_ON, 0}, +{0x2758, 0x275e, GRUB_BIDI_TYPE_ON, 0}, +{0x2761, 0x2794, GRUB_BIDI_TYPE_ON, 0}, +{0x2798, 0x27af, GRUB_BIDI_TYPE_ON, 0}, +{0x27b1, 0x27be, GRUB_BIDI_TYPE_ON, 0}, +{0x27c0, 0x27ca, GRUB_BIDI_TYPE_ON, 0}, +{0x27cc, 0x27cc, GRUB_BIDI_TYPE_ON, 0}, +{0x27d0, 0x27ff, GRUB_BIDI_TYPE_ON, 0}, +{0x2900, 0x2b4c, GRUB_BIDI_TYPE_ON, 0}, +{0x2b50, 0x2b54, GRUB_BIDI_TYPE_ON, 0}, +{0x2ce5, 0x2cea, GRUB_BIDI_TYPE_ON, 0}, +{0x2cf9, 0x2cff, GRUB_BIDI_TYPE_ON, 0}, +{0x2de0, 0x2dff, GRUB_BIDI_TYPE_NSM, 230}, +{0x2e00, 0x2e30, GRUB_BIDI_TYPE_ON, 0}, +{0x2e80, 0x2e99, GRUB_BIDI_TYPE_ON, 0}, +{0x2e9b, 0x2ef3, GRUB_BIDI_TYPE_ON, 0}, +{0x2f00, 0x2fd5, GRUB_BIDI_TYPE_ON, 0}, +{0x2ff0, 0x2ffb, GRUB_BIDI_TYPE_ON, 0}, +{0x3000, 0x3000, GRUB_BIDI_TYPE_WS, 0}, +{0x3001, 0x3004, GRUB_BIDI_TYPE_ON, 0}, +{0x3008, 0x3020, GRUB_BIDI_TYPE_ON, 0}, +{0x302a, 0x302a, GRUB_BIDI_TYPE_NSM, 218}, +{0x302b, 0x302b, GRUB_BIDI_TYPE_NSM, 228}, +{0x302c, 0x302c, GRUB_BIDI_TYPE_NSM, 232}, +{0x302d, 0x302d, GRUB_BIDI_TYPE_NSM, 222}, +{0x302e, 0x302f, GRUB_BIDI_TYPE_NSM, 224}, +{0x3030, 0x3030, GRUB_BIDI_TYPE_ON, 0}, +{0x3036, 0x3037, GRUB_BIDI_TYPE_ON, 0}, +{0x303d, 0x303f, GRUB_BIDI_TYPE_ON, 0}, +{0x3099, 0x309a, GRUB_BIDI_TYPE_NSM, 8}, +{0x309b, 0x309c, GRUB_BIDI_TYPE_ON, 0}, +{0x30a0, 0x30a0, GRUB_BIDI_TYPE_ON, 0}, +{0x30fb, 0x30fb, GRUB_BIDI_TYPE_ON, 0}, +{0x31c0, 0x31e3, GRUB_BIDI_TYPE_ON, 0}, +{0x321d, 0x321e, GRUB_BIDI_TYPE_ON, 0}, +{0x3250, 0x325f, GRUB_BIDI_TYPE_ON, 0}, +{0x327c, 0x327e, GRUB_BIDI_TYPE_ON, 0}, +{0x32b1, 0x32bf, GRUB_BIDI_TYPE_ON, 0}, +{0x32cc, 0x32cf, GRUB_BIDI_TYPE_ON, 0}, +{0x3377, 0x337a, GRUB_BIDI_TYPE_ON, 0}, +{0x33de, 0x33df, GRUB_BIDI_TYPE_ON, 0}, +{0x33ff, 0x33ff, GRUB_BIDI_TYPE_ON, 0}, +{0x4dc0, 0x4dff, GRUB_BIDI_TYPE_ON, 0}, +{0xa490, 0xa4c6, GRUB_BIDI_TYPE_ON, 0}, +{0xa60d, 0xa60f, GRUB_BIDI_TYPE_ON, 0}, +{0xa66f, 0xa66f, GRUB_BIDI_TYPE_NSM, 230}, +{0xa670, 0xa672, GRUB_BIDI_TYPE_NSM, 253}, +{0xa673, 0xa673, GRUB_BIDI_TYPE_ON, 0}, +{0xa67c, 0xa67d, GRUB_BIDI_TYPE_NSM, 230}, +{0xa67e, 0xa67f, GRUB_BIDI_TYPE_ON, 0}, +{0xa700, 0xa721, GRUB_BIDI_TYPE_ON, 0}, +{0xa788, 0xa788, GRUB_BIDI_TYPE_ON, 0}, +{0xa802, 0xa802, GRUB_BIDI_TYPE_NSM, 255}, +{0xa806, 0xa806, GRUB_BIDI_TYPE_NSM, 9}, +{0xa80b, 0xa80b, GRUB_BIDI_TYPE_NSM, 255}, +{0xa823, 0xa824, GRUB_BIDI_TYPE_L, 254}, +{0xa825, 0xa826, GRUB_BIDI_TYPE_NSM, 255}, +{0xa827, 0xa827, GRUB_BIDI_TYPE_L, 254}, +{0xa828, 0xa82b, GRUB_BIDI_TYPE_ON, 0}, +{0xa874, 0xa877, GRUB_BIDI_TYPE_ON, 0}, +{0xa880, 0xa881, GRUB_BIDI_TYPE_L, 254}, +{0xa8b4, 0xa8c3, GRUB_BIDI_TYPE_L, 254}, +{0xa8c4, 0xa8c4, GRUB_BIDI_TYPE_NSM, 9}, +{0xa926, 0xa92a, GRUB_BIDI_TYPE_NSM, 255}, +{0xa92b, 0xa92d, GRUB_BIDI_TYPE_NSM, 220}, +{0xa947, 0xa951, GRUB_BIDI_TYPE_NSM, 255}, +{0xa952, 0xa952, GRUB_BIDI_TYPE_L, 254}, +{0xa953, 0xa953, GRUB_BIDI_TYPE_L, 9}, +{0xaa29, 0xaa2e, GRUB_BIDI_TYPE_NSM, 255}, +{0xaa2f, 0xaa30, GRUB_BIDI_TYPE_L, 254}, +{0xaa31, 0xaa32, GRUB_BIDI_TYPE_NSM, 255}, +{0xaa33, 0xaa34, GRUB_BIDI_TYPE_L, 254}, +{0xaa35, 0xaa36, GRUB_BIDI_TYPE_NSM, 255}, +{0xaa43, 0xaa43, GRUB_BIDI_TYPE_NSM, 255}, +{0xaa4c, 0xaa4c, GRUB_BIDI_TYPE_NSM, 255}, +{0xaa4d, 0xaa4d, GRUB_BIDI_TYPE_L, 254}, +{0xfb1d, 0xfb1d, GRUB_BIDI_TYPE_R, 0}, +{0xfb1e, 0xfb1e, GRUB_BIDI_TYPE_NSM, 26}, +{0xfb1f, 0xfb28, GRUB_BIDI_TYPE_R, 0}, +{0xfb29, 0xfb29, GRUB_BIDI_TYPE_ES, 0}, +{0xfb2a, 0xfb36, GRUB_BIDI_TYPE_R, 0}, +{0xfb38, 0xfb3c, GRUB_BIDI_TYPE_R, 0}, +{0xfb3e, 0xfb3e, GRUB_BIDI_TYPE_R, 0}, +{0xfb40, 0xfb41, GRUB_BIDI_TYPE_R, 0}, +{0xfb43, 0xfb44, GRUB_BIDI_TYPE_R, 0}, +{0xfb46, 0xfb4f, GRUB_BIDI_TYPE_R, 0}, +{0xfb50, 0xfbb1, GRUB_BIDI_TYPE_AL, 0}, +{0xfbd3, 0xfd3d, GRUB_BIDI_TYPE_AL, 0}, +{0xfd3e, 0xfd3f, GRUB_BIDI_TYPE_ON, 0}, +{0xfd50, 0xfd8f, GRUB_BIDI_TYPE_AL, 0}, +{0xfd92, 0xfdc7, GRUB_BIDI_TYPE_AL, 0}, +{0xfdf0, 0xfdfc, GRUB_BIDI_TYPE_AL, 0}, +{0xfdfd, 0xfdfd, GRUB_BIDI_TYPE_ON, 0}, +{0xfe00, 0xfe0f, GRUB_BIDI_TYPE_NSM, 255}, +{0xfe10, 0xfe19, GRUB_BIDI_TYPE_ON, 0}, +{0xfe20, 0xfe26, GRUB_BIDI_TYPE_NSM, 230}, +{0xfe30, 0xfe4f, GRUB_BIDI_TYPE_ON, 0}, +{0xfe50, 0xfe50, GRUB_BIDI_TYPE_CS, 0}, +{0xfe51, 0xfe51, GRUB_BIDI_TYPE_ON, 0}, +{0xfe52, 0xfe52, GRUB_BIDI_TYPE_CS, 0}, +{0xfe54, 0xfe54, GRUB_BIDI_TYPE_ON, 0}, +{0xfe55, 0xfe55, GRUB_BIDI_TYPE_CS, 0}, +{0xfe56, 0xfe5e, GRUB_BIDI_TYPE_ON, 0}, +{0xfe5f, 0xfe5f, GRUB_BIDI_TYPE_ET, 0}, +{0xfe60, 0xfe61, GRUB_BIDI_TYPE_ON, 0}, +{0xfe62, 0xfe63, GRUB_BIDI_TYPE_ES, 0}, +{0xfe64, 0xfe66, GRUB_BIDI_TYPE_ON, 0}, +{0xfe68, 0xfe68, GRUB_BIDI_TYPE_ON, 0}, +{0xfe69, 0xfe6a, GRUB_BIDI_TYPE_ET, 0}, +{0xfe6b, 0xfe6b, GRUB_BIDI_TYPE_ON, 0}, +{0xfe70, 0xfe74, GRUB_BIDI_TYPE_AL, 0}, +{0xfe76, 0xfefc, GRUB_BIDI_TYPE_AL, 0}, +{0xfeff, 0xfeff, GRUB_BIDI_TYPE_BN, 0}, +{0xff01, 0xff02, GRUB_BIDI_TYPE_ON, 0}, +{0xff03, 0xff05, GRUB_BIDI_TYPE_ET, 0}, +{0xff06, 0xff0a, GRUB_BIDI_TYPE_ON, 0}, +{0xff0b, 0xff0b, GRUB_BIDI_TYPE_ES, 0}, +{0xff0c, 0xff0c, GRUB_BIDI_TYPE_CS, 0}, +{0xff0d, 0xff0d, GRUB_BIDI_TYPE_ES, 0}, +{0xff0e, 0xff0f, GRUB_BIDI_TYPE_CS, 0}, +{0xff10, 0xff19, GRUB_BIDI_TYPE_EN, 0}, +{0xff1a, 0xff1a, GRUB_BIDI_TYPE_CS, 0}, +{0xff1b, 0xff20, GRUB_BIDI_TYPE_ON, 0}, +{0xff3b, 0xff40, GRUB_BIDI_TYPE_ON, 0}, +{0xff5b, 0xff65, GRUB_BIDI_TYPE_ON, 0}, +{0xffe0, 0xffe1, GRUB_BIDI_TYPE_ET, 0}, +{0xffe2, 0xffe4, GRUB_BIDI_TYPE_ON, 0}, +{0xffe5, 0xffe6, GRUB_BIDI_TYPE_ET, 0}, +{0xffe8, 0xffee, GRUB_BIDI_TYPE_ON, 0}, +{0xfff9, 0xfffd, GRUB_BIDI_TYPE_ON, 0}, +{0x10101, 0x10101, GRUB_BIDI_TYPE_ON, 0}, +{0x10140, 0x1018a, GRUB_BIDI_TYPE_ON, 0}, +{0x10190, 0x1019b, GRUB_BIDI_TYPE_ON, 0}, +{0x101fd, 0x101fd, GRUB_BIDI_TYPE_NSM, 220}, +{0x10800, 0x10805, GRUB_BIDI_TYPE_R, 0}, +{0x10808, 0x10808, GRUB_BIDI_TYPE_R, 0}, +{0x1080a, 0x10835, GRUB_BIDI_TYPE_R, 0}, +{0x10837, 0x10838, GRUB_BIDI_TYPE_R, 0}, +{0x1083c, 0x1083c, GRUB_BIDI_TYPE_R, 0}, +{0x1083f, 0x1083f, GRUB_BIDI_TYPE_R, 0}, +{0x10900, 0x10919, GRUB_BIDI_TYPE_R, 0}, +{0x1091f, 0x1091f, GRUB_BIDI_TYPE_ON, 0}, +{0x10920, 0x10939, GRUB_BIDI_TYPE_R, 0}, +{0x1093f, 0x1093f, GRUB_BIDI_TYPE_R, 0}, +{0x10a00, 0x10a00, GRUB_BIDI_TYPE_R, 0}, +{0x10a01, 0x10a03, GRUB_BIDI_TYPE_NSM, 255}, +{0x10a05, 0x10a06, GRUB_BIDI_TYPE_NSM, 255}, +{0x10a0c, 0x10a0c, GRUB_BIDI_TYPE_NSM, 255}, +{0x10a0d, 0x10a0d, GRUB_BIDI_TYPE_NSM, 220}, +{0x10a0e, 0x10a0e, GRUB_BIDI_TYPE_NSM, 255}, +{0x10a0f, 0x10a0f, GRUB_BIDI_TYPE_NSM, 230}, +{0x10a10, 0x10a13, GRUB_BIDI_TYPE_R, 0}, +{0x10a15, 0x10a17, GRUB_BIDI_TYPE_R, 0}, +{0x10a19, 0x10a33, GRUB_BIDI_TYPE_R, 0}, +{0x10a38, 0x10a38, GRUB_BIDI_TYPE_NSM, 230}, +{0x10a39, 0x10a39, GRUB_BIDI_TYPE_NSM, 1}, +{0x10a3a, 0x10a3a, GRUB_BIDI_TYPE_NSM, 220}, +{0x10a3f, 0x10a3f, GRUB_BIDI_TYPE_NSM, 9}, +{0x10a40, 0x10a47, GRUB_BIDI_TYPE_R, 0}, +{0x10a50, 0x10a58, GRUB_BIDI_TYPE_R, 0}, +{0x1d165, 0x1d166, GRUB_BIDI_TYPE_L, 216}, +{0x1d167, 0x1d169, GRUB_BIDI_TYPE_NSM, 1}, +{0x1d16d, 0x1d16d, GRUB_BIDI_TYPE_L, 226}, +{0x1d16e, 0x1d172, GRUB_BIDI_TYPE_L, 216}, +{0x1d173, 0x1d17a, GRUB_BIDI_TYPE_BN, 0}, +{0x1d17b, 0x1d182, GRUB_BIDI_TYPE_NSM, 220}, +{0x1d185, 0x1d189, GRUB_BIDI_TYPE_NSM, 230}, +{0x1d18a, 0x1d18b, GRUB_BIDI_TYPE_NSM, 220}, +{0x1d1aa, 0x1d1ad, GRUB_BIDI_TYPE_NSM, 230}, +{0x1d200, 0x1d241, GRUB_BIDI_TYPE_ON, 0}, +{0x1d242, 0x1d244, GRUB_BIDI_TYPE_NSM, 230}, +{0x1d245, 0x1d245, GRUB_BIDI_TYPE_ON, 0}, +{0x1d300, 0x1d356, GRUB_BIDI_TYPE_ON, 0}, +{0x1d7ce, 0x1d7ff, GRUB_BIDI_TYPE_EN, 0}, +{0x1f000, 0x1f02b, GRUB_BIDI_TYPE_ON, 0}, +{0x1f030, 0x1f093, GRUB_BIDI_TYPE_ON, 0}, +{0xe0001, 0xe0001, GRUB_BIDI_TYPE_BN, 0}, +{0xe0020, 0xe007f, GRUB_BIDI_TYPE_BN, 0}, +{0xe0100, 0xe01ef, GRUB_BIDI_TYPE_NSM, 255}, +{0, 0, 0, 0}, }; \ No newline at end of file diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index a358ba5b0..2074c64b0 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -170,6 +170,9 @@ add_char (struct grub_font_info *font_info, FT_Face face, if ((*p_glyph) && ((*p_glyph)->char_code == char_code)) return; + if (glyph->next) + printf ("%x\n", char_code); + width = glyph->bitmap.width; height = glyph->bitmap.rows; diff --git a/util/import_bidi.py b/util/import_bidi.py deleted file mode 100644 index 543174ad9..000000000 --- a/util/import_bidi.py +++ /dev/null @@ -1,52 +0,0 @@ -#* -#* GRUB -- GRand Unified Bootloader -#* Copyright (C) 2010 Free Software Foundation, Inc. -#* -#* GRUB is free software: you can redistribute it and/or modify -#* it under the terms of the GNU General Public License as published by -#* the Free Software Foundation, either version 3 of the License, or -#* (at your option) any later version. -#* -#* GRUB is distributed in the hope that it will be useful, -#* but WITHOUT ANY WARRANTY; without even the implied warranty of -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#* GNU General Public License for more details. -#* -#* You should have received a copy of the GNU General Public License -#* along with GRUB. If not, see . -#* - -import re -import sys -import os -import datetime - -if len (sys.argv) < 3: - print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) - exit (0) -infile = open (sys.argv[1], "r") -outfile = open (sys.argv[2], "w") -outfile.write ("#include \n") -outfile.write ("\n") -outfile.write ("struct grub_bidi_compact_range grub_bidi_compact[] = {\n") - -begin = -2 -last = -2 -lasttype = "X" -for line in infile: - sp = line.split (";") - cur = int (sp[0], 16) - curtype = sp[4] - if last + 1 != cur or curtype != lasttype: - if begin != -2 and lasttype != "L": - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s},\n" \ - % (begin, last, lasttype))) - begin = cur - last = cur - lasttype = curtype -if lasttype != "L": - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s},\n" \ - % (begin, last, lasttype))) -outfile.write ("{0, 0, 0},\n") - -outfile.write ("};") diff --git a/util/import_unicode.py b/util/import_unicode.py new file mode 100644 index 000000000..adba3f938 --- /dev/null +++ b/util/import_unicode.py @@ -0,0 +1,67 @@ +#* +#* GRUB -- GRand Unified Bootloader +#* Copyright (C) 2010 Free Software Foundation, Inc. +#* +#* GRUB is free software: you can redistribute it and/or modify +#* it under the terms of the GNU General Public License as published by +#* the Free Software Foundation, either version 3 of the License, or +#* (at your option) any later version. +#* +#* GRUB is distributed in the hope that it will be useful, +#* but WITHOUT ANY WARRANTY; without even the implied warranty of +#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#* GNU General Public License for more details. +#* +#* You should have received a copy of the GNU General Public License +#* along with GRUB. If not, see . +#* + +import re +import sys +import os +import datetime + +if len (sys.argv) < 3: + print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) + exit (0) +infile = open (sys.argv[1], "r") +outfile = open (sys.argv[2], "w") +outfile.write ("#include \n") +outfile.write ("\n") +outfile.write ("struct grub_unicode_compact_range grub_unicode_compact[] = {\n") + +begincode = -2 +lastcode = -2 +lastbiditype = "X" +lastcombtype = -1 +for line in infile: + sp = line.split (";") + curcode = int (sp[0], 16) + curbiditype = sp[4] + curcombtype = int (sp[3], 10) + if curcombtype <= 255 and curcombtype >= 253: + print ("UnicodeData.txt uses combination type %d. Conflict." \ + % curcombtype) + raise + if curcombtype == 0 and sp[2] == "Me": + curcombtype = 253 + if curcombtype == 0 and sp[2] == "Mc": + curcombtype = 254 + if curcombtype == 0 and sp[2] == "Mn": + curcombtype = 255 + if lastcode + 1 != curcode or curbiditype != lastbiditype \ + or curcombtype != lastcombtype: + if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0): + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d},\n" \ + % (begincode, lastcode, lastbiditype, \ + lastcombtype))) + begincode = curcode + lastcode = curcode + lastbiditype = curbiditype + lastcombtype = curcombtype +if lastbiditype != "L" or lastcombtype != 0: + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d},\n" \ + % (begincode, lastcode, lastbiditype, lastcombtype))) +outfile.write ("{0, 0, 0, 0},\n") + +outfile.write ("};") From 97ea65d432235ac23f93b8b2eb297e40fedda3f9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 7 Jan 2010 21:25:56 +0100 Subject: [PATCH 013/503] Add mirroring and stacked combining marks --- font/font.c | 192 +++++++++-- include/grub/font.h | 2 + include/grub/unicode.h | 7 +- unidata.c | 715 ----------------------------------------- util/import_unicode.py | 23 +- 5 files changed, 193 insertions(+), 746 deletions(-) delete mode 100644 unidata.c diff --git a/font/font.c b/font/font.c index 54b6a1048..6655a29ae 100644 --- a/font/font.c +++ b/font/font.c @@ -850,6 +850,13 @@ grub_font_get_descent (grub_font_t font) return font->descent; } +/* FIXME: not correct for all fonts. */ +int +grub_font_get_xheight (grub_font_t font) +{ + return font->ascent / 2; +} + /* 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 @@ -1041,6 +1048,40 @@ grub_font_blit_glyph (struct grub_font_glyph *target, } } +static void +grub_font_blit_glyph_mirror (struct grub_font_glyph *target, + struct grub_font_glyph *src, + unsigned dx, unsigned dy) +{ + unsigned tgt_bit, src_byte, tgt_byte; + signed src_bit; + unsigned i, j; + for (i = 0; i < src->height; i++) + { + src_bit = (src->width * i + src->width - 1) % 8; + src_byte = (src->width * i + src->width - 1) / 8; + tgt_bit = (target->width * (dy + i) + dx) % 8; + tgt_byte = (target->width * (dy + i) + dx) / 8; + for (j = 0; j < src->width; j++) + { + target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit) + & 0x80) >> tgt_bit; + src_bit--; + tgt_bit++; + if (src_bit == -1) + { + src_byte--; + src_bit = 7; + } + if (tgt_bit == 8) + { + tgt_byte++; + tgt_bit = 0; + } + } + } +} + static inline enum grub_comb_type get_comb_type (grub_uint32_t c) { @@ -1079,6 +1120,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, grub_uint16_t height; grub_int16_t offset_x; grub_int16_t offset_y; + grub_int16_t curtop, curbottom; grub_uint16_t device_width; struct grub_font_glyph *main_glyph; struct grub_font_glyph **combining_glyphs; @@ -1093,12 +1135,12 @@ grub_font_construct_glyph (grub_font_t hinted_font, return grub_font_dup_glyph (unknown_glyph); } - if (!glyph_id->ncomb) + if (!glyph_id->ncomb && !glyph_id->attributes) return grub_font_dup_glyph (main_glyph); combining_glyphs = grub_malloc (sizeof (combining_glyphs[0]) * glyph_id->ncomb); - if (!combining_glyphs) + if (glyph_id->ncomb && !combining_glyphs) { grub_errno = GRUB_ERR_NONE; return grub_font_dup_glyph (main_glyph); @@ -1121,6 +1163,43 @@ grub_font_construct_glyph (grub_font_t hinted_font, combtype = get_comb_type (glyph_id->combining[i]); switch (combtype) { + case GRUB_UNICODE_STACK_ABOVE: + { + grub_int16_t space; + space = combining_glyphs[i]->offset_y + - grub_font_get_xheight (combining_glyphs[i]->font); + if (space < 1) + space = 1; + if (width < combining_glyphs[i]->width) + { + offset_x -= (combining_glyphs[i]->width - width) / 2; + width = combining_glyphs[i]->width; + } + if (device_width < combining_glyphs[i]->width) + device_width = combining_glyphs[i]->width; + height += combining_glyphs[i]->height + space; + } + break; + + case GRUB_UNICODE_STACK_BELOW: + { + grub_int16_t space; + space = -(combining_glyphs[i]->offset_y + + combining_glyphs[i]->height); + if (space < 1) + space = 1; + if (width < combining_glyphs[i]->width) + { + offset_x -= (combining_glyphs[i]->width - width) / 2; + width = combining_glyphs[i]->width; + } + if (device_width < combining_glyphs[i]->width) + device_width = combining_glyphs[i]->width; + height += combining_glyphs[i]->height + space; + offset_y -= combining_glyphs[i]->height + space; + } + break; + default: { /* Default handling. Just draw combining character on top @@ -1166,9 +1245,18 @@ grub_font_construct_glyph (grub_font_t hinted_font, glyph->offset_y = offset_y; glyph->device_width = device_width; - grub_font_blit_glyph (glyph, main_glyph, main_glyph->offset_x - offset_x, - (height + offset_y) - - (main_glyph->height + main_glyph->offset_y)); + if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) + grub_font_blit_glyph_mirror (glyph, main_glyph, + main_glyph->offset_x - offset_x, + (height + offset_y) + - (main_glyph->height + main_glyph->offset_y)); + else + grub_font_blit_glyph (glyph, main_glyph, main_glyph->offset_x - offset_x, + (height + offset_y) + - (main_glyph->height + main_glyph->offset_y)); + + curtop = main_glyph->height + main_glyph->offset_y; + curbottom = main_glyph->offset_y; for (i = 0; i < glyph_id->ncomb; i++) { @@ -1178,6 +1266,37 @@ grub_font_construct_glyph (grub_font_t hinted_font, combtype = get_comb_type (glyph_id->combining[i]); switch (combtype) { + case GRUB_UNICODE_STACK_ABOVE: + { + grub_int16_t space; + space = combining_glyphs[i]->offset_y + - grub_font_get_xheight (combining_glyphs[i]->font); + if (space < 0) + space = 1; + + curtop += combining_glyphs[i]->height + space; + grub_font_blit_glyph (glyph, combining_glyphs[i], + (width - combining_glyphs[i]->width) / 2, + (height + offset_y) - curtop); + } + break; + + case GRUB_UNICODE_STACK_BELOW: + { + grub_int16_t space; + space = -(combining_glyphs[i]->offset_y + + combining_glyphs[i]->height); + if (space < 0) + space = 1; + + curbottom -= space; + grub_font_blit_glyph (glyph, combining_glyphs[i], + (width - combining_glyphs[i]->width) / 2, + (height + offset_y) - curbottom); + curbottom -= combining_glyphs[i]->height; + } + break; + default: { /* Default handling. Just draw combining character on top @@ -1247,27 +1366,39 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, glyph->width, glyph->height); } +static grub_uint8_t *bidi_types = NULL; + +static void +unpack_bidi (void) +{ + unsigned i; + struct grub_unicode_compact_range *cur; + + bidi_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (!bidi_types) + { + grub_errno = GRUB_ERR_NONE; + return; + } + for (cur = grub_unicode_compact; cur->end; cur++) + for (i = cur->start; i <= cur->end + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + if (cur->bidi_mirror) + bidi_types[i] = cur->bidi_type | 0x80; + else + bidi_types[i] = cur->bidi_type | 0x00; +} + static inline enum grub_bidi_type get_bidi_type (grub_uint32_t c) { - static grub_uint8_t *bidi_types = NULL; struct grub_unicode_compact_range *cur; if (!bidi_types) - { - unsigned i; - bidi_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); - if (bidi_types) - for (cur = grub_unicode_compact; cur->end; cur++) - for (i = cur->start; i <= cur->end - && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) - bidi_types[i] = cur->bidi_type; - else - grub_errno = GRUB_ERR_NONE; - } + unpack_bidi (); if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return bidi_types[c]; + return bidi_types[c] & 0x7f; for (cur = grub_unicode_compact; cur->end; cur++) if (cur->start <= c && c <= cur->end) @@ -1276,6 +1407,24 @@ get_bidi_type (grub_uint32_t c) return GRUB_BIDI_TYPE_L; } +static inline int +is_mirrored (grub_uint32_t c) +{ + struct grub_unicode_compact_range *cur; + + if (!bidi_types) + unpack_bidi (); + + if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return !!(bidi_types[c] & 0x80); + + for (cur = grub_unicode_compact; cur->end; cur++) + if (cur->start <= c && c <= cur->end) + return cur->bidi_mirror; + + return 0; +} + static grub_ssize_t grub_err_bidi_logical_to_visual (grub_uint32_t *logical, grub_size_t logical_len, @@ -1450,6 +1599,7 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, resolved_types[visual_len] = type; visual[visual_len].base = logical[i]; visual[visual_len].variant = 0; + visual[visual_len].attributes = 0; visual[visual_len].ncomb = 0; visual[visual_len].combining = NULL; visual_len++; @@ -1629,7 +1779,7 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, if (levels[i] > max_level) max_level = levels[i]; if (levels[i] < min_odd_level && (levels[i] & 1)) - min_odd_level = levels[i]; + min_odd_level = levels[i]; } for (j = max_level; j >= min_odd_level; j--) { @@ -1644,6 +1794,10 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, } } + for (i = 0; i < visual_len; i++) + if (is_mirrored (visual[i].base) && levels[i]) + visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + grub_free (levels); *visual_out = visual; diff --git a/include/grub/font.h b/include/grub/font.h index 8a5f3ac7d..f8bc4c4e2 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -96,6 +96,8 @@ int grub_font_get_leading (grub_font_t font); int grub_font_get_height (grub_font_t font); +int grub_font_get_xheight (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, diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 79d553eec..20c7c4167 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -27,6 +27,7 @@ struct grub_unicode_compact_range grub_uint32_t end:21; grub_uint8_t bidi_type:5; grub_uint8_t comb_type; + grub_uint8_t bidi_mirror:1; } __attribute__ ((packed)); enum grub_bidi_type @@ -67,13 +68,13 @@ enum grub_comb_type struct grub_unicode_glyph { grub_uint32_t base; - /* Unicode permits 256 variation selectors but since we need a value - for "default" we have to use grub_uint16_t. */ - grub_uint16_t variant; + grub_uint16_t variant:9; + grub_uint8_t attributes:1; grub_size_t ncomb; grub_uint32_t *combining; }; +#define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 #define GRUB_UNICODE_VARIATION_SELECTOR_1 0xfe00 #define GRUB_UNICODE_VARIATION_SELECTOR_16 0xfe0f #define GRUB_UNICODE_VARIATION_SELECTOR_17 0xe0100 diff --git a/unidata.c b/unidata.c deleted file mode 100644 index 02d0f9712..000000000 --- a/unidata.c +++ /dev/null @@ -1,715 +0,0 @@ -#include - -struct grub_unicode_compact_range grub_unicode_compact[] = { -{0x0, 0x8, GRUB_BIDI_TYPE_BN, 0}, -{0x9, 0x9, GRUB_BIDI_TYPE_S, 0}, -{0xa, 0xa, GRUB_BIDI_TYPE_B, 0}, -{0xb, 0xb, GRUB_BIDI_TYPE_S, 0}, -{0xc, 0xc, GRUB_BIDI_TYPE_WS, 0}, -{0xd, 0xd, GRUB_BIDI_TYPE_B, 0}, -{0xe, 0x1b, GRUB_BIDI_TYPE_BN, 0}, -{0x1c, 0x1e, GRUB_BIDI_TYPE_B, 0}, -{0x1f, 0x1f, GRUB_BIDI_TYPE_S, 0}, -{0x20, 0x20, GRUB_BIDI_TYPE_WS, 0}, -{0x21, 0x22, GRUB_BIDI_TYPE_ON, 0}, -{0x23, 0x25, GRUB_BIDI_TYPE_ET, 0}, -{0x26, 0x2a, GRUB_BIDI_TYPE_ON, 0}, -{0x2b, 0x2b, GRUB_BIDI_TYPE_ES, 0}, -{0x2c, 0x2c, GRUB_BIDI_TYPE_CS, 0}, -{0x2d, 0x2d, GRUB_BIDI_TYPE_ES, 0}, -{0x2e, 0x2f, GRUB_BIDI_TYPE_CS, 0}, -{0x30, 0x39, GRUB_BIDI_TYPE_EN, 0}, -{0x3a, 0x3a, GRUB_BIDI_TYPE_CS, 0}, -{0x3b, 0x40, GRUB_BIDI_TYPE_ON, 0}, -{0x5b, 0x60, GRUB_BIDI_TYPE_ON, 0}, -{0x7b, 0x7e, GRUB_BIDI_TYPE_ON, 0}, -{0x7f, 0x84, GRUB_BIDI_TYPE_BN, 0}, -{0x85, 0x85, GRUB_BIDI_TYPE_B, 0}, -{0x86, 0x9f, GRUB_BIDI_TYPE_BN, 0}, -{0xa0, 0xa0, GRUB_BIDI_TYPE_CS, 0}, -{0xa1, 0xa1, GRUB_BIDI_TYPE_ON, 0}, -{0xa2, 0xa5, GRUB_BIDI_TYPE_ET, 0}, -{0xa6, 0xa9, GRUB_BIDI_TYPE_ON, 0}, -{0xab, 0xac, GRUB_BIDI_TYPE_ON, 0}, -{0xad, 0xad, GRUB_BIDI_TYPE_BN, 0}, -{0xae, 0xaf, GRUB_BIDI_TYPE_ON, 0}, -{0xb0, 0xb1, GRUB_BIDI_TYPE_ET, 0}, -{0xb2, 0xb3, GRUB_BIDI_TYPE_EN, 0}, -{0xb4, 0xb4, GRUB_BIDI_TYPE_ON, 0}, -{0xb6, 0xb8, GRUB_BIDI_TYPE_ON, 0}, -{0xb9, 0xb9, GRUB_BIDI_TYPE_EN, 0}, -{0xbb, 0xbf, GRUB_BIDI_TYPE_ON, 0}, -{0xd7, 0xd7, GRUB_BIDI_TYPE_ON, 0}, -{0xf7, 0xf7, GRUB_BIDI_TYPE_ON, 0}, -{0x2b9, 0x2ba, GRUB_BIDI_TYPE_ON, 0}, -{0x2c2, 0x2cf, GRUB_BIDI_TYPE_ON, 0}, -{0x2d2, 0x2df, GRUB_BIDI_TYPE_ON, 0}, -{0x2e5, 0x2ed, GRUB_BIDI_TYPE_ON, 0}, -{0x2ef, 0x2ff, GRUB_BIDI_TYPE_ON, 0}, -{0x300, 0x314, GRUB_BIDI_TYPE_NSM, 230}, -{0x315, 0x315, GRUB_BIDI_TYPE_NSM, 232}, -{0x316, 0x319, GRUB_BIDI_TYPE_NSM, 220}, -{0x31a, 0x31a, GRUB_BIDI_TYPE_NSM, 232}, -{0x31b, 0x31b, GRUB_BIDI_TYPE_NSM, 216}, -{0x31c, 0x320, GRUB_BIDI_TYPE_NSM, 220}, -{0x321, 0x322, GRUB_BIDI_TYPE_NSM, 202}, -{0x323, 0x326, GRUB_BIDI_TYPE_NSM, 220}, -{0x327, 0x328, GRUB_BIDI_TYPE_NSM, 202}, -{0x329, 0x333, GRUB_BIDI_TYPE_NSM, 220}, -{0x334, 0x338, GRUB_BIDI_TYPE_NSM, 1}, -{0x339, 0x33c, GRUB_BIDI_TYPE_NSM, 220}, -{0x33d, 0x344, GRUB_BIDI_TYPE_NSM, 230}, -{0x345, 0x345, GRUB_BIDI_TYPE_NSM, 240}, -{0x346, 0x346, GRUB_BIDI_TYPE_NSM, 230}, -{0x347, 0x349, GRUB_BIDI_TYPE_NSM, 220}, -{0x34a, 0x34c, GRUB_BIDI_TYPE_NSM, 230}, -{0x34d, 0x34e, GRUB_BIDI_TYPE_NSM, 220}, -{0x34f, 0x34f, GRUB_BIDI_TYPE_NSM, 255}, -{0x350, 0x352, GRUB_BIDI_TYPE_NSM, 230}, -{0x353, 0x356, GRUB_BIDI_TYPE_NSM, 220}, -{0x357, 0x357, GRUB_BIDI_TYPE_NSM, 230}, -{0x358, 0x358, GRUB_BIDI_TYPE_NSM, 232}, -{0x359, 0x35a, GRUB_BIDI_TYPE_NSM, 220}, -{0x35b, 0x35b, GRUB_BIDI_TYPE_NSM, 230}, -{0x35c, 0x35c, GRUB_BIDI_TYPE_NSM, 233}, -{0x35d, 0x35e, GRUB_BIDI_TYPE_NSM, 234}, -{0x35f, 0x35f, GRUB_BIDI_TYPE_NSM, 233}, -{0x360, 0x361, GRUB_BIDI_TYPE_NSM, 234}, -{0x362, 0x362, GRUB_BIDI_TYPE_NSM, 233}, -{0x363, 0x36f, GRUB_BIDI_TYPE_NSM, 230}, -{0x374, 0x375, GRUB_BIDI_TYPE_ON, 0}, -{0x37e, 0x37e, GRUB_BIDI_TYPE_ON, 0}, -{0x384, 0x385, GRUB_BIDI_TYPE_ON, 0}, -{0x387, 0x387, GRUB_BIDI_TYPE_ON, 0}, -{0x3f6, 0x3f6, GRUB_BIDI_TYPE_ON, 0}, -{0x483, 0x487, GRUB_BIDI_TYPE_NSM, 230}, -{0x488, 0x489, GRUB_BIDI_TYPE_NSM, 253}, -{0x58a, 0x58a, GRUB_BIDI_TYPE_ON, 0}, -{0x591, 0x591, GRUB_BIDI_TYPE_NSM, 220}, -{0x592, 0x595, GRUB_BIDI_TYPE_NSM, 230}, -{0x596, 0x596, GRUB_BIDI_TYPE_NSM, 220}, -{0x597, 0x599, GRUB_BIDI_TYPE_NSM, 230}, -{0x59a, 0x59a, GRUB_BIDI_TYPE_NSM, 222}, -{0x59b, 0x59b, GRUB_BIDI_TYPE_NSM, 220}, -{0x59c, 0x5a1, GRUB_BIDI_TYPE_NSM, 230}, -{0x5a2, 0x5a7, GRUB_BIDI_TYPE_NSM, 220}, -{0x5a8, 0x5a9, GRUB_BIDI_TYPE_NSM, 230}, -{0x5aa, 0x5aa, GRUB_BIDI_TYPE_NSM, 220}, -{0x5ab, 0x5ac, GRUB_BIDI_TYPE_NSM, 230}, -{0x5ad, 0x5ad, GRUB_BIDI_TYPE_NSM, 222}, -{0x5ae, 0x5ae, GRUB_BIDI_TYPE_NSM, 228}, -{0x5af, 0x5af, GRUB_BIDI_TYPE_NSM, 230}, -{0x5b0, 0x5b0, GRUB_BIDI_TYPE_NSM, 10}, -{0x5b1, 0x5b1, GRUB_BIDI_TYPE_NSM, 11}, -{0x5b2, 0x5b2, GRUB_BIDI_TYPE_NSM, 12}, -{0x5b3, 0x5b3, GRUB_BIDI_TYPE_NSM, 13}, -{0x5b4, 0x5b4, GRUB_BIDI_TYPE_NSM, 14}, -{0x5b5, 0x5b5, GRUB_BIDI_TYPE_NSM, 15}, -{0x5b6, 0x5b6, GRUB_BIDI_TYPE_NSM, 16}, -{0x5b7, 0x5b7, GRUB_BIDI_TYPE_NSM, 17}, -{0x5b8, 0x5b8, GRUB_BIDI_TYPE_NSM, 18}, -{0x5b9, 0x5ba, GRUB_BIDI_TYPE_NSM, 19}, -{0x5bb, 0x5bb, GRUB_BIDI_TYPE_NSM, 20}, -{0x5bc, 0x5bc, GRUB_BIDI_TYPE_NSM, 21}, -{0x5bd, 0x5bd, GRUB_BIDI_TYPE_NSM, 22}, -{0x5be, 0x5be, GRUB_BIDI_TYPE_R, 0}, -{0x5bf, 0x5bf, GRUB_BIDI_TYPE_NSM, 23}, -{0x5c0, 0x5c0, GRUB_BIDI_TYPE_R, 0}, -{0x5c1, 0x5c1, GRUB_BIDI_TYPE_NSM, 24}, -{0x5c2, 0x5c2, GRUB_BIDI_TYPE_NSM, 25}, -{0x5c3, 0x5c3, GRUB_BIDI_TYPE_R, 0}, -{0x5c4, 0x5c4, GRUB_BIDI_TYPE_NSM, 230}, -{0x5c5, 0x5c5, GRUB_BIDI_TYPE_NSM, 220}, -{0x5c6, 0x5c6, GRUB_BIDI_TYPE_R, 0}, -{0x5c7, 0x5c7, GRUB_BIDI_TYPE_NSM, 18}, -{0x5d0, 0x5ea, GRUB_BIDI_TYPE_R, 0}, -{0x5f0, 0x5f4, GRUB_BIDI_TYPE_R, 0}, -{0x600, 0x603, GRUB_BIDI_TYPE_AN, 0}, -{0x606, 0x607, GRUB_BIDI_TYPE_ON, 0}, -{0x608, 0x608, GRUB_BIDI_TYPE_AL, 0}, -{0x609, 0x60a, GRUB_BIDI_TYPE_ET, 0}, -{0x60b, 0x60b, GRUB_BIDI_TYPE_AL, 0}, -{0x60c, 0x60c, GRUB_BIDI_TYPE_CS, 0}, -{0x60d, 0x60d, GRUB_BIDI_TYPE_AL, 0}, -{0x60e, 0x60f, GRUB_BIDI_TYPE_ON, 0}, -{0x610, 0x617, GRUB_BIDI_TYPE_NSM, 230}, -{0x618, 0x618, GRUB_BIDI_TYPE_NSM, 30}, -{0x619, 0x619, GRUB_BIDI_TYPE_NSM, 31}, -{0x61a, 0x61a, GRUB_BIDI_TYPE_NSM, 32}, -{0x61b, 0x61b, GRUB_BIDI_TYPE_AL, 0}, -{0x61e, 0x61f, GRUB_BIDI_TYPE_AL, 0}, -{0x621, 0x64a, GRUB_BIDI_TYPE_AL, 0}, -{0x64b, 0x64b, GRUB_BIDI_TYPE_NSM, 27}, -{0x64c, 0x64c, GRUB_BIDI_TYPE_NSM, 28}, -{0x64d, 0x64d, GRUB_BIDI_TYPE_NSM, 29}, -{0x64e, 0x64e, GRUB_BIDI_TYPE_NSM, 30}, -{0x64f, 0x64f, GRUB_BIDI_TYPE_NSM, 31}, -{0x650, 0x650, GRUB_BIDI_TYPE_NSM, 32}, -{0x651, 0x651, GRUB_BIDI_TYPE_NSM, 33}, -{0x652, 0x652, GRUB_BIDI_TYPE_NSM, 34}, -{0x653, 0x654, GRUB_BIDI_TYPE_NSM, 230}, -{0x655, 0x656, GRUB_BIDI_TYPE_NSM, 220}, -{0x657, 0x65b, GRUB_BIDI_TYPE_NSM, 230}, -{0x65c, 0x65c, GRUB_BIDI_TYPE_NSM, 220}, -{0x65d, 0x65e, GRUB_BIDI_TYPE_NSM, 230}, -{0x660, 0x669, GRUB_BIDI_TYPE_AN, 0}, -{0x66a, 0x66a, GRUB_BIDI_TYPE_ET, 0}, -{0x66b, 0x66c, GRUB_BIDI_TYPE_AN, 0}, -{0x66d, 0x66f, GRUB_BIDI_TYPE_AL, 0}, -{0x670, 0x670, GRUB_BIDI_TYPE_NSM, 35}, -{0x671, 0x6d5, GRUB_BIDI_TYPE_AL, 0}, -{0x6d6, 0x6dc, GRUB_BIDI_TYPE_NSM, 230}, -{0x6dd, 0x6dd, GRUB_BIDI_TYPE_AN, 0}, -{0x6de, 0x6de, GRUB_BIDI_TYPE_NSM, 253}, -{0x6df, 0x6e2, GRUB_BIDI_TYPE_NSM, 230}, -{0x6e3, 0x6e3, GRUB_BIDI_TYPE_NSM, 220}, -{0x6e4, 0x6e4, GRUB_BIDI_TYPE_NSM, 230}, -{0x6e5, 0x6e6, GRUB_BIDI_TYPE_AL, 0}, -{0x6e7, 0x6e8, GRUB_BIDI_TYPE_NSM, 230}, -{0x6e9, 0x6e9, GRUB_BIDI_TYPE_ON, 0}, -{0x6ea, 0x6ea, GRUB_BIDI_TYPE_NSM, 220}, -{0x6eb, 0x6ec, GRUB_BIDI_TYPE_NSM, 230}, -{0x6ed, 0x6ed, GRUB_BIDI_TYPE_NSM, 220}, -{0x6ee, 0x6ef, GRUB_BIDI_TYPE_AL, 0}, -{0x6f0, 0x6f9, GRUB_BIDI_TYPE_EN, 0}, -{0x6fa, 0x70d, GRUB_BIDI_TYPE_AL, 0}, -{0x70f, 0x70f, GRUB_BIDI_TYPE_BN, 0}, -{0x710, 0x710, GRUB_BIDI_TYPE_AL, 0}, -{0x711, 0x711, GRUB_BIDI_TYPE_NSM, 36}, -{0x712, 0x72f, GRUB_BIDI_TYPE_AL, 0}, -{0x730, 0x730, GRUB_BIDI_TYPE_NSM, 230}, -{0x731, 0x731, GRUB_BIDI_TYPE_NSM, 220}, -{0x732, 0x733, GRUB_BIDI_TYPE_NSM, 230}, -{0x734, 0x734, GRUB_BIDI_TYPE_NSM, 220}, -{0x735, 0x736, GRUB_BIDI_TYPE_NSM, 230}, -{0x737, 0x739, GRUB_BIDI_TYPE_NSM, 220}, -{0x73a, 0x73a, GRUB_BIDI_TYPE_NSM, 230}, -{0x73b, 0x73c, GRUB_BIDI_TYPE_NSM, 220}, -{0x73d, 0x73d, GRUB_BIDI_TYPE_NSM, 230}, -{0x73e, 0x73e, GRUB_BIDI_TYPE_NSM, 220}, -{0x73f, 0x741, GRUB_BIDI_TYPE_NSM, 230}, -{0x742, 0x742, GRUB_BIDI_TYPE_NSM, 220}, -{0x743, 0x743, GRUB_BIDI_TYPE_NSM, 230}, -{0x744, 0x744, GRUB_BIDI_TYPE_NSM, 220}, -{0x745, 0x745, GRUB_BIDI_TYPE_NSM, 230}, -{0x746, 0x746, GRUB_BIDI_TYPE_NSM, 220}, -{0x747, 0x747, GRUB_BIDI_TYPE_NSM, 230}, -{0x748, 0x748, GRUB_BIDI_TYPE_NSM, 220}, -{0x749, 0x74a, GRUB_BIDI_TYPE_NSM, 230}, -{0x74d, 0x7a5, GRUB_BIDI_TYPE_AL, 0}, -{0x7a6, 0x7b0, GRUB_BIDI_TYPE_NSM, 255}, -{0x7b1, 0x7b1, GRUB_BIDI_TYPE_AL, 0}, -{0x7c0, 0x7ea, GRUB_BIDI_TYPE_R, 0}, -{0x7eb, 0x7f1, GRUB_BIDI_TYPE_NSM, 230}, -{0x7f2, 0x7f2, GRUB_BIDI_TYPE_NSM, 220}, -{0x7f3, 0x7f3, GRUB_BIDI_TYPE_NSM, 230}, -{0x7f4, 0x7f5, GRUB_BIDI_TYPE_R, 0}, -{0x7f6, 0x7f9, GRUB_BIDI_TYPE_ON, 0}, -{0x7fa, 0x7fa, GRUB_BIDI_TYPE_R, 0}, -{0x901, 0x902, GRUB_BIDI_TYPE_NSM, 255}, -{0x903, 0x903, GRUB_BIDI_TYPE_L, 254}, -{0x93c, 0x93c, GRUB_BIDI_TYPE_NSM, 7}, -{0x93e, 0x940, GRUB_BIDI_TYPE_L, 254}, -{0x941, 0x948, GRUB_BIDI_TYPE_NSM, 255}, -{0x949, 0x94c, GRUB_BIDI_TYPE_L, 254}, -{0x94d, 0x94d, GRUB_BIDI_TYPE_NSM, 9}, -{0x951, 0x951, GRUB_BIDI_TYPE_NSM, 230}, -{0x952, 0x952, GRUB_BIDI_TYPE_NSM, 220}, -{0x953, 0x954, GRUB_BIDI_TYPE_NSM, 230}, -{0x962, 0x963, GRUB_BIDI_TYPE_NSM, 255}, -{0x981, 0x981, GRUB_BIDI_TYPE_NSM, 255}, -{0x982, 0x983, GRUB_BIDI_TYPE_L, 254}, -{0x9bc, 0x9bc, GRUB_BIDI_TYPE_NSM, 7}, -{0x9be, 0x9c0, GRUB_BIDI_TYPE_L, 254}, -{0x9c1, 0x9c4, GRUB_BIDI_TYPE_NSM, 255}, -{0x9c7, 0x9c8, GRUB_BIDI_TYPE_L, 254}, -{0x9cb, 0x9cc, GRUB_BIDI_TYPE_L, 254}, -{0x9cd, 0x9cd, GRUB_BIDI_TYPE_NSM, 9}, -{0x9d7, 0x9d7, GRUB_BIDI_TYPE_L, 254}, -{0x9e2, 0x9e3, GRUB_BIDI_TYPE_NSM, 255}, -{0x9f2, 0x9f3, GRUB_BIDI_TYPE_ET, 0}, -{0xa01, 0xa02, GRUB_BIDI_TYPE_NSM, 255}, -{0xa03, 0xa03, GRUB_BIDI_TYPE_L, 254}, -{0xa3c, 0xa3c, GRUB_BIDI_TYPE_NSM, 7}, -{0xa3e, 0xa40, GRUB_BIDI_TYPE_L, 254}, -{0xa41, 0xa42, GRUB_BIDI_TYPE_NSM, 255}, -{0xa47, 0xa48, GRUB_BIDI_TYPE_NSM, 255}, -{0xa4b, 0xa4c, GRUB_BIDI_TYPE_NSM, 255}, -{0xa4d, 0xa4d, GRUB_BIDI_TYPE_NSM, 9}, -{0xa51, 0xa51, GRUB_BIDI_TYPE_NSM, 255}, -{0xa70, 0xa71, GRUB_BIDI_TYPE_NSM, 255}, -{0xa75, 0xa75, GRUB_BIDI_TYPE_NSM, 255}, -{0xa81, 0xa82, GRUB_BIDI_TYPE_NSM, 255}, -{0xa83, 0xa83, GRUB_BIDI_TYPE_L, 254}, -{0xabc, 0xabc, GRUB_BIDI_TYPE_NSM, 7}, -{0xabe, 0xac0, GRUB_BIDI_TYPE_L, 254}, -{0xac1, 0xac5, GRUB_BIDI_TYPE_NSM, 255}, -{0xac7, 0xac8, GRUB_BIDI_TYPE_NSM, 255}, -{0xac9, 0xac9, GRUB_BIDI_TYPE_L, 254}, -{0xacb, 0xacc, GRUB_BIDI_TYPE_L, 254}, -{0xacd, 0xacd, GRUB_BIDI_TYPE_NSM, 9}, -{0xae2, 0xae3, GRUB_BIDI_TYPE_NSM, 255}, -{0xaf1, 0xaf1, GRUB_BIDI_TYPE_ET, 0}, -{0xb01, 0xb01, GRUB_BIDI_TYPE_NSM, 255}, -{0xb02, 0xb03, GRUB_BIDI_TYPE_L, 254}, -{0xb3c, 0xb3c, GRUB_BIDI_TYPE_NSM, 7}, -{0xb3e, 0xb3e, GRUB_BIDI_TYPE_L, 254}, -{0xb3f, 0xb3f, GRUB_BIDI_TYPE_NSM, 255}, -{0xb40, 0xb40, GRUB_BIDI_TYPE_L, 254}, -{0xb41, 0xb44, GRUB_BIDI_TYPE_NSM, 255}, -{0xb47, 0xb48, GRUB_BIDI_TYPE_L, 254}, -{0xb4b, 0xb4c, GRUB_BIDI_TYPE_L, 254}, -{0xb4d, 0xb4d, GRUB_BIDI_TYPE_NSM, 9}, -{0xb56, 0xb56, GRUB_BIDI_TYPE_NSM, 255}, -{0xb57, 0xb57, GRUB_BIDI_TYPE_L, 254}, -{0xb62, 0xb63, GRUB_BIDI_TYPE_NSM, 255}, -{0xb82, 0xb82, GRUB_BIDI_TYPE_NSM, 255}, -{0xbbe, 0xbbf, GRUB_BIDI_TYPE_L, 254}, -{0xbc0, 0xbc0, GRUB_BIDI_TYPE_NSM, 255}, -{0xbc1, 0xbc2, GRUB_BIDI_TYPE_L, 254}, -{0xbc6, 0xbc8, GRUB_BIDI_TYPE_L, 254}, -{0xbca, 0xbcc, GRUB_BIDI_TYPE_L, 254}, -{0xbcd, 0xbcd, GRUB_BIDI_TYPE_NSM, 9}, -{0xbd7, 0xbd7, GRUB_BIDI_TYPE_L, 254}, -{0xbf3, 0xbf8, GRUB_BIDI_TYPE_ON, 0}, -{0xbf9, 0xbf9, GRUB_BIDI_TYPE_ET, 0}, -{0xbfa, 0xbfa, GRUB_BIDI_TYPE_ON, 0}, -{0xc01, 0xc03, GRUB_BIDI_TYPE_L, 254}, -{0xc3e, 0xc40, GRUB_BIDI_TYPE_NSM, 255}, -{0xc41, 0xc44, GRUB_BIDI_TYPE_L, 254}, -{0xc46, 0xc48, GRUB_BIDI_TYPE_NSM, 255}, -{0xc4a, 0xc4c, GRUB_BIDI_TYPE_NSM, 255}, -{0xc4d, 0xc4d, GRUB_BIDI_TYPE_NSM, 9}, -{0xc55, 0xc55, GRUB_BIDI_TYPE_NSM, 84}, -{0xc56, 0xc56, GRUB_BIDI_TYPE_NSM, 91}, -{0xc62, 0xc63, GRUB_BIDI_TYPE_NSM, 255}, -{0xc78, 0xc7e, GRUB_BIDI_TYPE_ON, 0}, -{0xc82, 0xc83, GRUB_BIDI_TYPE_L, 254}, -{0xcbc, 0xcbc, GRUB_BIDI_TYPE_NSM, 7}, -{0xcbe, 0xcbe, GRUB_BIDI_TYPE_L, 254}, -{0xcbf, 0xcbf, GRUB_BIDI_TYPE_L, 255}, -{0xcc0, 0xcc4, GRUB_BIDI_TYPE_L, 254}, -{0xcc6, 0xcc6, GRUB_BIDI_TYPE_L, 255}, -{0xcc7, 0xcc8, GRUB_BIDI_TYPE_L, 254}, -{0xcca, 0xccb, GRUB_BIDI_TYPE_L, 254}, -{0xccc, 0xccc, GRUB_BIDI_TYPE_NSM, 255}, -{0xccd, 0xccd, GRUB_BIDI_TYPE_NSM, 9}, -{0xcd5, 0xcd6, GRUB_BIDI_TYPE_L, 254}, -{0xce2, 0xce3, GRUB_BIDI_TYPE_NSM, 255}, -{0xcf1, 0xcf2, GRUB_BIDI_TYPE_ON, 0}, -{0xd02, 0xd03, GRUB_BIDI_TYPE_L, 254}, -{0xd3e, 0xd40, GRUB_BIDI_TYPE_L, 254}, -{0xd41, 0xd44, GRUB_BIDI_TYPE_NSM, 255}, -{0xd46, 0xd48, GRUB_BIDI_TYPE_L, 254}, -{0xd4a, 0xd4c, GRUB_BIDI_TYPE_L, 254}, -{0xd4d, 0xd4d, GRUB_BIDI_TYPE_NSM, 9}, -{0xd57, 0xd57, GRUB_BIDI_TYPE_L, 254}, -{0xd62, 0xd63, GRUB_BIDI_TYPE_NSM, 255}, -{0xd82, 0xd83, GRUB_BIDI_TYPE_L, 254}, -{0xdca, 0xdca, GRUB_BIDI_TYPE_NSM, 9}, -{0xdcf, 0xdd1, GRUB_BIDI_TYPE_L, 254}, -{0xdd2, 0xdd4, GRUB_BIDI_TYPE_NSM, 255}, -{0xdd6, 0xdd6, GRUB_BIDI_TYPE_NSM, 255}, -{0xdd8, 0xddf, GRUB_BIDI_TYPE_L, 254}, -{0xdf2, 0xdf3, GRUB_BIDI_TYPE_L, 254}, -{0xe31, 0xe31, GRUB_BIDI_TYPE_NSM, 255}, -{0xe34, 0xe37, GRUB_BIDI_TYPE_NSM, 255}, -{0xe38, 0xe39, GRUB_BIDI_TYPE_NSM, 103}, -{0xe3a, 0xe3a, GRUB_BIDI_TYPE_NSM, 9}, -{0xe3f, 0xe3f, GRUB_BIDI_TYPE_ET, 0}, -{0xe47, 0xe47, GRUB_BIDI_TYPE_NSM, 255}, -{0xe48, 0xe4b, GRUB_BIDI_TYPE_NSM, 107}, -{0xe4c, 0xe4e, GRUB_BIDI_TYPE_NSM, 255}, -{0xeb1, 0xeb1, GRUB_BIDI_TYPE_NSM, 255}, -{0xeb4, 0xeb7, GRUB_BIDI_TYPE_NSM, 255}, -{0xeb8, 0xeb9, GRUB_BIDI_TYPE_NSM, 118}, -{0xebb, 0xebc, GRUB_BIDI_TYPE_NSM, 255}, -{0xec8, 0xecb, GRUB_BIDI_TYPE_NSM, 122}, -{0xecc, 0xecd, GRUB_BIDI_TYPE_NSM, 255}, -{0xf18, 0xf19, GRUB_BIDI_TYPE_NSM, 220}, -{0xf35, 0xf35, GRUB_BIDI_TYPE_NSM, 220}, -{0xf37, 0xf37, GRUB_BIDI_TYPE_NSM, 220}, -{0xf39, 0xf39, GRUB_BIDI_TYPE_NSM, 216}, -{0xf3a, 0xf3d, GRUB_BIDI_TYPE_ON, 0}, -{0xf3e, 0xf3f, GRUB_BIDI_TYPE_L, 254}, -{0xf71, 0xf71, GRUB_BIDI_TYPE_NSM, 129}, -{0xf72, 0xf72, GRUB_BIDI_TYPE_NSM, 130}, -{0xf73, 0xf73, GRUB_BIDI_TYPE_NSM, 255}, -{0xf74, 0xf74, GRUB_BIDI_TYPE_NSM, 132}, -{0xf75, 0xf79, GRUB_BIDI_TYPE_NSM, 255}, -{0xf7a, 0xf7d, GRUB_BIDI_TYPE_NSM, 130}, -{0xf7e, 0xf7e, GRUB_BIDI_TYPE_NSM, 255}, -{0xf7f, 0xf7f, GRUB_BIDI_TYPE_L, 254}, -{0xf80, 0xf80, GRUB_BIDI_TYPE_NSM, 130}, -{0xf81, 0xf81, GRUB_BIDI_TYPE_NSM, 255}, -{0xf82, 0xf83, GRUB_BIDI_TYPE_NSM, 230}, -{0xf84, 0xf84, GRUB_BIDI_TYPE_NSM, 9}, -{0xf86, 0xf87, GRUB_BIDI_TYPE_NSM, 230}, -{0xf90, 0xf97, GRUB_BIDI_TYPE_NSM, 255}, -{0xf99, 0xfbc, GRUB_BIDI_TYPE_NSM, 255}, -{0xfc6, 0xfc6, GRUB_BIDI_TYPE_NSM, 220}, -{0x102b, 0x102c, GRUB_BIDI_TYPE_L, 254}, -{0x102d, 0x1030, GRUB_BIDI_TYPE_NSM, 255}, -{0x1031, 0x1031, GRUB_BIDI_TYPE_L, 254}, -{0x1032, 0x1036, GRUB_BIDI_TYPE_NSM, 255}, -{0x1037, 0x1037, GRUB_BIDI_TYPE_NSM, 7}, -{0x1038, 0x1038, GRUB_BIDI_TYPE_L, 254}, -{0x1039, 0x103a, GRUB_BIDI_TYPE_NSM, 9}, -{0x103b, 0x103c, GRUB_BIDI_TYPE_L, 254}, -{0x103d, 0x103e, GRUB_BIDI_TYPE_NSM, 255}, -{0x1056, 0x1057, GRUB_BIDI_TYPE_L, 254}, -{0x1058, 0x1059, GRUB_BIDI_TYPE_NSM, 255}, -{0x105e, 0x1060, GRUB_BIDI_TYPE_NSM, 255}, -{0x1062, 0x1064, GRUB_BIDI_TYPE_L, 254}, -{0x1067, 0x106d, GRUB_BIDI_TYPE_L, 254}, -{0x1071, 0x1074, GRUB_BIDI_TYPE_NSM, 255}, -{0x1082, 0x1082, GRUB_BIDI_TYPE_NSM, 255}, -{0x1083, 0x1084, GRUB_BIDI_TYPE_L, 254}, -{0x1085, 0x1086, GRUB_BIDI_TYPE_NSM, 255}, -{0x1087, 0x108c, GRUB_BIDI_TYPE_L, 254}, -{0x108d, 0x108d, GRUB_BIDI_TYPE_NSM, 220}, -{0x108f, 0x108f, GRUB_BIDI_TYPE_L, 254}, -{0x135f, 0x135f, GRUB_BIDI_TYPE_NSM, 230}, -{0x1390, 0x1399, GRUB_BIDI_TYPE_ON, 0}, -{0x1680, 0x1680, GRUB_BIDI_TYPE_WS, 0}, -{0x169b, 0x169c, GRUB_BIDI_TYPE_ON, 0}, -{0x1712, 0x1713, GRUB_BIDI_TYPE_NSM, 255}, -{0x1714, 0x1714, GRUB_BIDI_TYPE_NSM, 9}, -{0x1732, 0x1733, GRUB_BIDI_TYPE_NSM, 255}, -{0x1734, 0x1734, GRUB_BIDI_TYPE_NSM, 9}, -{0x1752, 0x1753, GRUB_BIDI_TYPE_NSM, 255}, -{0x1772, 0x1773, GRUB_BIDI_TYPE_NSM, 255}, -{0x17b6, 0x17b6, GRUB_BIDI_TYPE_L, 254}, -{0x17b7, 0x17bd, GRUB_BIDI_TYPE_NSM, 255}, -{0x17be, 0x17c5, GRUB_BIDI_TYPE_L, 254}, -{0x17c6, 0x17c6, GRUB_BIDI_TYPE_NSM, 255}, -{0x17c7, 0x17c8, GRUB_BIDI_TYPE_L, 254}, -{0x17c9, 0x17d1, GRUB_BIDI_TYPE_NSM, 255}, -{0x17d2, 0x17d2, GRUB_BIDI_TYPE_NSM, 9}, -{0x17d3, 0x17d3, GRUB_BIDI_TYPE_NSM, 255}, -{0x17db, 0x17db, GRUB_BIDI_TYPE_ET, 0}, -{0x17dd, 0x17dd, GRUB_BIDI_TYPE_NSM, 230}, -{0x17f0, 0x17f9, GRUB_BIDI_TYPE_ON, 0}, -{0x1800, 0x180a, GRUB_BIDI_TYPE_ON, 0}, -{0x180b, 0x180d, GRUB_BIDI_TYPE_NSM, 255}, -{0x180e, 0x180e, GRUB_BIDI_TYPE_WS, 0}, -{0x18a9, 0x18a9, GRUB_BIDI_TYPE_NSM, 228}, -{0x1920, 0x1922, GRUB_BIDI_TYPE_NSM, 255}, -{0x1923, 0x1926, GRUB_BIDI_TYPE_L, 254}, -{0x1927, 0x1928, GRUB_BIDI_TYPE_NSM, 255}, -{0x1929, 0x192b, GRUB_BIDI_TYPE_L, 254}, -{0x1930, 0x1931, GRUB_BIDI_TYPE_L, 254}, -{0x1932, 0x1932, GRUB_BIDI_TYPE_NSM, 255}, -{0x1933, 0x1938, GRUB_BIDI_TYPE_L, 254}, -{0x1939, 0x1939, GRUB_BIDI_TYPE_NSM, 222}, -{0x193a, 0x193a, GRUB_BIDI_TYPE_NSM, 230}, -{0x193b, 0x193b, GRUB_BIDI_TYPE_NSM, 220}, -{0x1940, 0x1940, GRUB_BIDI_TYPE_ON, 0}, -{0x1944, 0x1945, GRUB_BIDI_TYPE_ON, 0}, -{0x19b0, 0x19c0, GRUB_BIDI_TYPE_L, 254}, -{0x19c8, 0x19c9, GRUB_BIDI_TYPE_L, 254}, -{0x19de, 0x19ff, GRUB_BIDI_TYPE_ON, 0}, -{0x1a17, 0x1a17, GRUB_BIDI_TYPE_NSM, 230}, -{0x1a18, 0x1a18, GRUB_BIDI_TYPE_NSM, 220}, -{0x1a19, 0x1a1b, GRUB_BIDI_TYPE_L, 254}, -{0x1b00, 0x1b03, GRUB_BIDI_TYPE_NSM, 255}, -{0x1b04, 0x1b04, GRUB_BIDI_TYPE_L, 254}, -{0x1b34, 0x1b34, GRUB_BIDI_TYPE_NSM, 7}, -{0x1b35, 0x1b35, GRUB_BIDI_TYPE_L, 254}, -{0x1b36, 0x1b3a, GRUB_BIDI_TYPE_NSM, 255}, -{0x1b3b, 0x1b3b, GRUB_BIDI_TYPE_L, 254}, -{0x1b3c, 0x1b3c, GRUB_BIDI_TYPE_NSM, 255}, -{0x1b3d, 0x1b41, GRUB_BIDI_TYPE_L, 254}, -{0x1b42, 0x1b42, GRUB_BIDI_TYPE_NSM, 255}, -{0x1b43, 0x1b43, GRUB_BIDI_TYPE_L, 254}, -{0x1b44, 0x1b44, GRUB_BIDI_TYPE_L, 9}, -{0x1b6b, 0x1b6b, GRUB_BIDI_TYPE_NSM, 230}, -{0x1b6c, 0x1b6c, GRUB_BIDI_TYPE_NSM, 220}, -{0x1b6d, 0x1b73, GRUB_BIDI_TYPE_NSM, 230}, -{0x1b80, 0x1b81, GRUB_BIDI_TYPE_NSM, 255}, -{0x1b82, 0x1b82, GRUB_BIDI_TYPE_L, 254}, -{0x1ba1, 0x1ba1, GRUB_BIDI_TYPE_L, 254}, -{0x1ba2, 0x1ba5, GRUB_BIDI_TYPE_NSM, 255}, -{0x1ba6, 0x1ba7, GRUB_BIDI_TYPE_L, 254}, -{0x1ba8, 0x1ba9, GRUB_BIDI_TYPE_NSM, 255}, -{0x1baa, 0x1baa, GRUB_BIDI_TYPE_L, 9}, -{0x1c24, 0x1c2b, GRUB_BIDI_TYPE_L, 254}, -{0x1c2c, 0x1c33, GRUB_BIDI_TYPE_NSM, 255}, -{0x1c34, 0x1c35, GRUB_BIDI_TYPE_L, 254}, -{0x1c36, 0x1c36, GRUB_BIDI_TYPE_NSM, 255}, -{0x1c37, 0x1c37, GRUB_BIDI_TYPE_NSM, 7}, -{0x1dc0, 0x1dc1, GRUB_BIDI_TYPE_NSM, 230}, -{0x1dc2, 0x1dc2, GRUB_BIDI_TYPE_NSM, 220}, -{0x1dc3, 0x1dc9, GRUB_BIDI_TYPE_NSM, 230}, -{0x1dca, 0x1dca, GRUB_BIDI_TYPE_NSM, 220}, -{0x1dcb, 0x1dcc, GRUB_BIDI_TYPE_NSM, 230}, -{0x1dcd, 0x1dcd, GRUB_BIDI_TYPE_NSM, 234}, -{0x1dce, 0x1dce, GRUB_BIDI_TYPE_NSM, 214}, -{0x1dcf, 0x1dcf, GRUB_BIDI_TYPE_NSM, 220}, -{0x1dd0, 0x1dd0, GRUB_BIDI_TYPE_NSM, 202}, -{0x1dd1, 0x1de6, GRUB_BIDI_TYPE_NSM, 230}, -{0x1dfe, 0x1dfe, GRUB_BIDI_TYPE_NSM, 230}, -{0x1dff, 0x1dff, GRUB_BIDI_TYPE_NSM, 220}, -{0x1fbd, 0x1fbd, GRUB_BIDI_TYPE_ON, 0}, -{0x1fbf, 0x1fc1, GRUB_BIDI_TYPE_ON, 0}, -{0x1fcd, 0x1fcf, GRUB_BIDI_TYPE_ON, 0}, -{0x1fdd, 0x1fdf, GRUB_BIDI_TYPE_ON, 0}, -{0x1fed, 0x1fef, GRUB_BIDI_TYPE_ON, 0}, -{0x1ffd, 0x1ffe, GRUB_BIDI_TYPE_ON, 0}, -{0x2000, 0x200a, GRUB_BIDI_TYPE_WS, 0}, -{0x200b, 0x200d, GRUB_BIDI_TYPE_BN, 0}, -{0x200f, 0x200f, GRUB_BIDI_TYPE_R, 0}, -{0x2010, 0x2027, GRUB_BIDI_TYPE_ON, 0}, -{0x2028, 0x2028, GRUB_BIDI_TYPE_WS, 0}, -{0x2029, 0x2029, GRUB_BIDI_TYPE_B, 0}, -{0x202a, 0x202a, GRUB_BIDI_TYPE_LRE, 0}, -{0x202b, 0x202b, GRUB_BIDI_TYPE_RLE, 0}, -{0x202c, 0x202c, GRUB_BIDI_TYPE_PDF, 0}, -{0x202d, 0x202d, GRUB_BIDI_TYPE_LRO, 0}, -{0x202e, 0x202e, GRUB_BIDI_TYPE_RLO, 0}, -{0x202f, 0x202f, GRUB_BIDI_TYPE_CS, 0}, -{0x2030, 0x2034, GRUB_BIDI_TYPE_ET, 0}, -{0x2035, 0x2043, GRUB_BIDI_TYPE_ON, 0}, -{0x2044, 0x2044, GRUB_BIDI_TYPE_CS, 0}, -{0x2045, 0x205e, GRUB_BIDI_TYPE_ON, 0}, -{0x205f, 0x205f, GRUB_BIDI_TYPE_WS, 0}, -{0x2060, 0x2064, GRUB_BIDI_TYPE_BN, 0}, -{0x206a, 0x206f, GRUB_BIDI_TYPE_BN, 0}, -{0x2070, 0x2070, GRUB_BIDI_TYPE_EN, 0}, -{0x2074, 0x2079, GRUB_BIDI_TYPE_EN, 0}, -{0x207a, 0x207b, GRUB_BIDI_TYPE_ES, 0}, -{0x207c, 0x207e, GRUB_BIDI_TYPE_ON, 0}, -{0x2080, 0x2089, GRUB_BIDI_TYPE_EN, 0}, -{0x208a, 0x208b, GRUB_BIDI_TYPE_ES, 0}, -{0x208c, 0x208e, GRUB_BIDI_TYPE_ON, 0}, -{0x20a0, 0x20b5, GRUB_BIDI_TYPE_ET, 0}, -{0x20d0, 0x20d1, GRUB_BIDI_TYPE_NSM, 230}, -{0x20d2, 0x20d3, GRUB_BIDI_TYPE_NSM, 1}, -{0x20d4, 0x20d7, GRUB_BIDI_TYPE_NSM, 230}, -{0x20d8, 0x20da, GRUB_BIDI_TYPE_NSM, 1}, -{0x20db, 0x20dc, GRUB_BIDI_TYPE_NSM, 230}, -{0x20dd, 0x20e0, GRUB_BIDI_TYPE_NSM, 253}, -{0x20e1, 0x20e1, GRUB_BIDI_TYPE_NSM, 230}, -{0x20e2, 0x20e4, GRUB_BIDI_TYPE_NSM, 253}, -{0x20e5, 0x20e6, GRUB_BIDI_TYPE_NSM, 1}, -{0x20e7, 0x20e7, GRUB_BIDI_TYPE_NSM, 230}, -{0x20e8, 0x20e8, GRUB_BIDI_TYPE_NSM, 220}, -{0x20e9, 0x20e9, GRUB_BIDI_TYPE_NSM, 230}, -{0x20ea, 0x20eb, GRUB_BIDI_TYPE_NSM, 1}, -{0x20ec, 0x20ef, GRUB_BIDI_TYPE_NSM, 220}, -{0x20f0, 0x20f0, GRUB_BIDI_TYPE_NSM, 230}, -{0x2100, 0x2101, GRUB_BIDI_TYPE_ON, 0}, -{0x2103, 0x2106, GRUB_BIDI_TYPE_ON, 0}, -{0x2108, 0x2109, GRUB_BIDI_TYPE_ON, 0}, -{0x2114, 0x2114, GRUB_BIDI_TYPE_ON, 0}, -{0x2116, 0x2118, GRUB_BIDI_TYPE_ON, 0}, -{0x211e, 0x2123, GRUB_BIDI_TYPE_ON, 0}, -{0x2125, 0x2125, GRUB_BIDI_TYPE_ON, 0}, -{0x2127, 0x2127, GRUB_BIDI_TYPE_ON, 0}, -{0x2129, 0x2129, GRUB_BIDI_TYPE_ON, 0}, -{0x212e, 0x212e, GRUB_BIDI_TYPE_ET, 0}, -{0x213a, 0x213b, GRUB_BIDI_TYPE_ON, 0}, -{0x2140, 0x2144, GRUB_BIDI_TYPE_ON, 0}, -{0x214a, 0x214d, GRUB_BIDI_TYPE_ON, 0}, -{0x2153, 0x215f, GRUB_BIDI_TYPE_ON, 0}, -{0x2190, 0x2211, GRUB_BIDI_TYPE_ON, 0}, -{0x2212, 0x2212, GRUB_BIDI_TYPE_ES, 0}, -{0x2213, 0x2213, GRUB_BIDI_TYPE_ET, 0}, -{0x2214, 0x2335, GRUB_BIDI_TYPE_ON, 0}, -{0x237b, 0x2394, GRUB_BIDI_TYPE_ON, 0}, -{0x2396, 0x23e7, GRUB_BIDI_TYPE_ON, 0}, -{0x2400, 0x2426, GRUB_BIDI_TYPE_ON, 0}, -{0x2440, 0x244a, GRUB_BIDI_TYPE_ON, 0}, -{0x2460, 0x2487, GRUB_BIDI_TYPE_ON, 0}, -{0x2488, 0x249b, GRUB_BIDI_TYPE_EN, 0}, -{0x24ea, 0x269d, GRUB_BIDI_TYPE_ON, 0}, -{0x26a0, 0x26ab, GRUB_BIDI_TYPE_ON, 0}, -{0x26ad, 0x26bc, GRUB_BIDI_TYPE_ON, 0}, -{0x26c0, 0x26c3, GRUB_BIDI_TYPE_ON, 0}, -{0x2701, 0x2704, GRUB_BIDI_TYPE_ON, 0}, -{0x2706, 0x2709, GRUB_BIDI_TYPE_ON, 0}, -{0x270c, 0x2727, GRUB_BIDI_TYPE_ON, 0}, -{0x2729, 0x274b, GRUB_BIDI_TYPE_ON, 0}, -{0x274d, 0x274d, GRUB_BIDI_TYPE_ON, 0}, -{0x274f, 0x2752, GRUB_BIDI_TYPE_ON, 0}, -{0x2756, 0x2756, GRUB_BIDI_TYPE_ON, 0}, -{0x2758, 0x275e, GRUB_BIDI_TYPE_ON, 0}, -{0x2761, 0x2794, GRUB_BIDI_TYPE_ON, 0}, -{0x2798, 0x27af, GRUB_BIDI_TYPE_ON, 0}, -{0x27b1, 0x27be, GRUB_BIDI_TYPE_ON, 0}, -{0x27c0, 0x27ca, GRUB_BIDI_TYPE_ON, 0}, -{0x27cc, 0x27cc, GRUB_BIDI_TYPE_ON, 0}, -{0x27d0, 0x27ff, GRUB_BIDI_TYPE_ON, 0}, -{0x2900, 0x2b4c, GRUB_BIDI_TYPE_ON, 0}, -{0x2b50, 0x2b54, GRUB_BIDI_TYPE_ON, 0}, -{0x2ce5, 0x2cea, GRUB_BIDI_TYPE_ON, 0}, -{0x2cf9, 0x2cff, GRUB_BIDI_TYPE_ON, 0}, -{0x2de0, 0x2dff, GRUB_BIDI_TYPE_NSM, 230}, -{0x2e00, 0x2e30, GRUB_BIDI_TYPE_ON, 0}, -{0x2e80, 0x2e99, GRUB_BIDI_TYPE_ON, 0}, -{0x2e9b, 0x2ef3, GRUB_BIDI_TYPE_ON, 0}, -{0x2f00, 0x2fd5, GRUB_BIDI_TYPE_ON, 0}, -{0x2ff0, 0x2ffb, GRUB_BIDI_TYPE_ON, 0}, -{0x3000, 0x3000, GRUB_BIDI_TYPE_WS, 0}, -{0x3001, 0x3004, GRUB_BIDI_TYPE_ON, 0}, -{0x3008, 0x3020, GRUB_BIDI_TYPE_ON, 0}, -{0x302a, 0x302a, GRUB_BIDI_TYPE_NSM, 218}, -{0x302b, 0x302b, GRUB_BIDI_TYPE_NSM, 228}, -{0x302c, 0x302c, GRUB_BIDI_TYPE_NSM, 232}, -{0x302d, 0x302d, GRUB_BIDI_TYPE_NSM, 222}, -{0x302e, 0x302f, GRUB_BIDI_TYPE_NSM, 224}, -{0x3030, 0x3030, GRUB_BIDI_TYPE_ON, 0}, -{0x3036, 0x3037, GRUB_BIDI_TYPE_ON, 0}, -{0x303d, 0x303f, GRUB_BIDI_TYPE_ON, 0}, -{0x3099, 0x309a, GRUB_BIDI_TYPE_NSM, 8}, -{0x309b, 0x309c, GRUB_BIDI_TYPE_ON, 0}, -{0x30a0, 0x30a0, GRUB_BIDI_TYPE_ON, 0}, -{0x30fb, 0x30fb, GRUB_BIDI_TYPE_ON, 0}, -{0x31c0, 0x31e3, GRUB_BIDI_TYPE_ON, 0}, -{0x321d, 0x321e, GRUB_BIDI_TYPE_ON, 0}, -{0x3250, 0x325f, GRUB_BIDI_TYPE_ON, 0}, -{0x327c, 0x327e, GRUB_BIDI_TYPE_ON, 0}, -{0x32b1, 0x32bf, GRUB_BIDI_TYPE_ON, 0}, -{0x32cc, 0x32cf, GRUB_BIDI_TYPE_ON, 0}, -{0x3377, 0x337a, GRUB_BIDI_TYPE_ON, 0}, -{0x33de, 0x33df, GRUB_BIDI_TYPE_ON, 0}, -{0x33ff, 0x33ff, GRUB_BIDI_TYPE_ON, 0}, -{0x4dc0, 0x4dff, GRUB_BIDI_TYPE_ON, 0}, -{0xa490, 0xa4c6, GRUB_BIDI_TYPE_ON, 0}, -{0xa60d, 0xa60f, GRUB_BIDI_TYPE_ON, 0}, -{0xa66f, 0xa66f, GRUB_BIDI_TYPE_NSM, 230}, -{0xa670, 0xa672, GRUB_BIDI_TYPE_NSM, 253}, -{0xa673, 0xa673, GRUB_BIDI_TYPE_ON, 0}, -{0xa67c, 0xa67d, GRUB_BIDI_TYPE_NSM, 230}, -{0xa67e, 0xa67f, GRUB_BIDI_TYPE_ON, 0}, -{0xa700, 0xa721, GRUB_BIDI_TYPE_ON, 0}, -{0xa788, 0xa788, GRUB_BIDI_TYPE_ON, 0}, -{0xa802, 0xa802, GRUB_BIDI_TYPE_NSM, 255}, -{0xa806, 0xa806, GRUB_BIDI_TYPE_NSM, 9}, -{0xa80b, 0xa80b, GRUB_BIDI_TYPE_NSM, 255}, -{0xa823, 0xa824, GRUB_BIDI_TYPE_L, 254}, -{0xa825, 0xa826, GRUB_BIDI_TYPE_NSM, 255}, -{0xa827, 0xa827, GRUB_BIDI_TYPE_L, 254}, -{0xa828, 0xa82b, GRUB_BIDI_TYPE_ON, 0}, -{0xa874, 0xa877, GRUB_BIDI_TYPE_ON, 0}, -{0xa880, 0xa881, GRUB_BIDI_TYPE_L, 254}, -{0xa8b4, 0xa8c3, GRUB_BIDI_TYPE_L, 254}, -{0xa8c4, 0xa8c4, GRUB_BIDI_TYPE_NSM, 9}, -{0xa926, 0xa92a, GRUB_BIDI_TYPE_NSM, 255}, -{0xa92b, 0xa92d, GRUB_BIDI_TYPE_NSM, 220}, -{0xa947, 0xa951, GRUB_BIDI_TYPE_NSM, 255}, -{0xa952, 0xa952, GRUB_BIDI_TYPE_L, 254}, -{0xa953, 0xa953, GRUB_BIDI_TYPE_L, 9}, -{0xaa29, 0xaa2e, GRUB_BIDI_TYPE_NSM, 255}, -{0xaa2f, 0xaa30, GRUB_BIDI_TYPE_L, 254}, -{0xaa31, 0xaa32, GRUB_BIDI_TYPE_NSM, 255}, -{0xaa33, 0xaa34, GRUB_BIDI_TYPE_L, 254}, -{0xaa35, 0xaa36, GRUB_BIDI_TYPE_NSM, 255}, -{0xaa43, 0xaa43, GRUB_BIDI_TYPE_NSM, 255}, -{0xaa4c, 0xaa4c, GRUB_BIDI_TYPE_NSM, 255}, -{0xaa4d, 0xaa4d, GRUB_BIDI_TYPE_L, 254}, -{0xfb1d, 0xfb1d, GRUB_BIDI_TYPE_R, 0}, -{0xfb1e, 0xfb1e, GRUB_BIDI_TYPE_NSM, 26}, -{0xfb1f, 0xfb28, GRUB_BIDI_TYPE_R, 0}, -{0xfb29, 0xfb29, GRUB_BIDI_TYPE_ES, 0}, -{0xfb2a, 0xfb36, GRUB_BIDI_TYPE_R, 0}, -{0xfb38, 0xfb3c, GRUB_BIDI_TYPE_R, 0}, -{0xfb3e, 0xfb3e, GRUB_BIDI_TYPE_R, 0}, -{0xfb40, 0xfb41, GRUB_BIDI_TYPE_R, 0}, -{0xfb43, 0xfb44, GRUB_BIDI_TYPE_R, 0}, -{0xfb46, 0xfb4f, GRUB_BIDI_TYPE_R, 0}, -{0xfb50, 0xfbb1, GRUB_BIDI_TYPE_AL, 0}, -{0xfbd3, 0xfd3d, GRUB_BIDI_TYPE_AL, 0}, -{0xfd3e, 0xfd3f, GRUB_BIDI_TYPE_ON, 0}, -{0xfd50, 0xfd8f, GRUB_BIDI_TYPE_AL, 0}, -{0xfd92, 0xfdc7, GRUB_BIDI_TYPE_AL, 0}, -{0xfdf0, 0xfdfc, GRUB_BIDI_TYPE_AL, 0}, -{0xfdfd, 0xfdfd, GRUB_BIDI_TYPE_ON, 0}, -{0xfe00, 0xfe0f, GRUB_BIDI_TYPE_NSM, 255}, -{0xfe10, 0xfe19, GRUB_BIDI_TYPE_ON, 0}, -{0xfe20, 0xfe26, GRUB_BIDI_TYPE_NSM, 230}, -{0xfe30, 0xfe4f, GRUB_BIDI_TYPE_ON, 0}, -{0xfe50, 0xfe50, GRUB_BIDI_TYPE_CS, 0}, -{0xfe51, 0xfe51, GRUB_BIDI_TYPE_ON, 0}, -{0xfe52, 0xfe52, GRUB_BIDI_TYPE_CS, 0}, -{0xfe54, 0xfe54, GRUB_BIDI_TYPE_ON, 0}, -{0xfe55, 0xfe55, GRUB_BIDI_TYPE_CS, 0}, -{0xfe56, 0xfe5e, GRUB_BIDI_TYPE_ON, 0}, -{0xfe5f, 0xfe5f, GRUB_BIDI_TYPE_ET, 0}, -{0xfe60, 0xfe61, GRUB_BIDI_TYPE_ON, 0}, -{0xfe62, 0xfe63, GRUB_BIDI_TYPE_ES, 0}, -{0xfe64, 0xfe66, GRUB_BIDI_TYPE_ON, 0}, -{0xfe68, 0xfe68, GRUB_BIDI_TYPE_ON, 0}, -{0xfe69, 0xfe6a, GRUB_BIDI_TYPE_ET, 0}, -{0xfe6b, 0xfe6b, GRUB_BIDI_TYPE_ON, 0}, -{0xfe70, 0xfe74, GRUB_BIDI_TYPE_AL, 0}, -{0xfe76, 0xfefc, GRUB_BIDI_TYPE_AL, 0}, -{0xfeff, 0xfeff, GRUB_BIDI_TYPE_BN, 0}, -{0xff01, 0xff02, GRUB_BIDI_TYPE_ON, 0}, -{0xff03, 0xff05, GRUB_BIDI_TYPE_ET, 0}, -{0xff06, 0xff0a, GRUB_BIDI_TYPE_ON, 0}, -{0xff0b, 0xff0b, GRUB_BIDI_TYPE_ES, 0}, -{0xff0c, 0xff0c, GRUB_BIDI_TYPE_CS, 0}, -{0xff0d, 0xff0d, GRUB_BIDI_TYPE_ES, 0}, -{0xff0e, 0xff0f, GRUB_BIDI_TYPE_CS, 0}, -{0xff10, 0xff19, GRUB_BIDI_TYPE_EN, 0}, -{0xff1a, 0xff1a, GRUB_BIDI_TYPE_CS, 0}, -{0xff1b, 0xff20, GRUB_BIDI_TYPE_ON, 0}, -{0xff3b, 0xff40, GRUB_BIDI_TYPE_ON, 0}, -{0xff5b, 0xff65, GRUB_BIDI_TYPE_ON, 0}, -{0xffe0, 0xffe1, GRUB_BIDI_TYPE_ET, 0}, -{0xffe2, 0xffe4, GRUB_BIDI_TYPE_ON, 0}, -{0xffe5, 0xffe6, GRUB_BIDI_TYPE_ET, 0}, -{0xffe8, 0xffee, GRUB_BIDI_TYPE_ON, 0}, -{0xfff9, 0xfffd, GRUB_BIDI_TYPE_ON, 0}, -{0x10101, 0x10101, GRUB_BIDI_TYPE_ON, 0}, -{0x10140, 0x1018a, GRUB_BIDI_TYPE_ON, 0}, -{0x10190, 0x1019b, GRUB_BIDI_TYPE_ON, 0}, -{0x101fd, 0x101fd, GRUB_BIDI_TYPE_NSM, 220}, -{0x10800, 0x10805, GRUB_BIDI_TYPE_R, 0}, -{0x10808, 0x10808, GRUB_BIDI_TYPE_R, 0}, -{0x1080a, 0x10835, GRUB_BIDI_TYPE_R, 0}, -{0x10837, 0x10838, GRUB_BIDI_TYPE_R, 0}, -{0x1083c, 0x1083c, GRUB_BIDI_TYPE_R, 0}, -{0x1083f, 0x1083f, GRUB_BIDI_TYPE_R, 0}, -{0x10900, 0x10919, GRUB_BIDI_TYPE_R, 0}, -{0x1091f, 0x1091f, GRUB_BIDI_TYPE_ON, 0}, -{0x10920, 0x10939, GRUB_BIDI_TYPE_R, 0}, -{0x1093f, 0x1093f, GRUB_BIDI_TYPE_R, 0}, -{0x10a00, 0x10a00, GRUB_BIDI_TYPE_R, 0}, -{0x10a01, 0x10a03, GRUB_BIDI_TYPE_NSM, 255}, -{0x10a05, 0x10a06, GRUB_BIDI_TYPE_NSM, 255}, -{0x10a0c, 0x10a0c, GRUB_BIDI_TYPE_NSM, 255}, -{0x10a0d, 0x10a0d, GRUB_BIDI_TYPE_NSM, 220}, -{0x10a0e, 0x10a0e, GRUB_BIDI_TYPE_NSM, 255}, -{0x10a0f, 0x10a0f, GRUB_BIDI_TYPE_NSM, 230}, -{0x10a10, 0x10a13, GRUB_BIDI_TYPE_R, 0}, -{0x10a15, 0x10a17, GRUB_BIDI_TYPE_R, 0}, -{0x10a19, 0x10a33, GRUB_BIDI_TYPE_R, 0}, -{0x10a38, 0x10a38, GRUB_BIDI_TYPE_NSM, 230}, -{0x10a39, 0x10a39, GRUB_BIDI_TYPE_NSM, 1}, -{0x10a3a, 0x10a3a, GRUB_BIDI_TYPE_NSM, 220}, -{0x10a3f, 0x10a3f, GRUB_BIDI_TYPE_NSM, 9}, -{0x10a40, 0x10a47, GRUB_BIDI_TYPE_R, 0}, -{0x10a50, 0x10a58, GRUB_BIDI_TYPE_R, 0}, -{0x1d165, 0x1d166, GRUB_BIDI_TYPE_L, 216}, -{0x1d167, 0x1d169, GRUB_BIDI_TYPE_NSM, 1}, -{0x1d16d, 0x1d16d, GRUB_BIDI_TYPE_L, 226}, -{0x1d16e, 0x1d172, GRUB_BIDI_TYPE_L, 216}, -{0x1d173, 0x1d17a, GRUB_BIDI_TYPE_BN, 0}, -{0x1d17b, 0x1d182, GRUB_BIDI_TYPE_NSM, 220}, -{0x1d185, 0x1d189, GRUB_BIDI_TYPE_NSM, 230}, -{0x1d18a, 0x1d18b, GRUB_BIDI_TYPE_NSM, 220}, -{0x1d1aa, 0x1d1ad, GRUB_BIDI_TYPE_NSM, 230}, -{0x1d200, 0x1d241, GRUB_BIDI_TYPE_ON, 0}, -{0x1d242, 0x1d244, GRUB_BIDI_TYPE_NSM, 230}, -{0x1d245, 0x1d245, GRUB_BIDI_TYPE_ON, 0}, -{0x1d300, 0x1d356, GRUB_BIDI_TYPE_ON, 0}, -{0x1d7ce, 0x1d7ff, GRUB_BIDI_TYPE_EN, 0}, -{0x1f000, 0x1f02b, GRUB_BIDI_TYPE_ON, 0}, -{0x1f030, 0x1f093, GRUB_BIDI_TYPE_ON, 0}, -{0xe0001, 0xe0001, GRUB_BIDI_TYPE_BN, 0}, -{0xe0020, 0xe007f, GRUB_BIDI_TYPE_BN, 0}, -{0xe0100, 0xe01ef, GRUB_BIDI_TYPE_NSM, 255}, -{0, 0, 0, 0}, -}; \ No newline at end of file diff --git a/util/import_unicode.py b/util/import_unicode.py index adba3f938..e2f0561f0 100644 --- a/util/import_unicode.py +++ b/util/import_unicode.py @@ -33,12 +33,14 @@ outfile.write ("struct grub_unicode_compact_range grub_unicode_compact[] = {\n") begincode = -2 lastcode = -2 lastbiditype = "X" +lastmirrortype = False lastcombtype = -1 for line in infile: sp = line.split (";") curcode = int (sp[0], 16) - curbiditype = sp[4] curcombtype = int (sp[3], 10) + curbiditype = sp[4] + curmirrortype = (sp[9] == "Y") if curcombtype <= 255 and curcombtype >= 253: print ("UnicodeData.txt uses combination type %d. Conflict." \ % curcombtype) @@ -50,18 +52,21 @@ for line in infile: if curcombtype == 0 and sp[2] == "Mn": curcombtype = 255 if lastcode + 1 != curcode or curbiditype != lastbiditype \ - or curcombtype != lastcombtype: - if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0): - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d},\n" \ + or curcombtype != lastcombtype or curmirrortype != lastmirrortype: + if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0 or \ + lastmirrortype): + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d},\n" \ % (begincode, lastcode, lastbiditype, \ - lastcombtype))) + lastcombtype, lastmirrortype))) begincode = curcode lastcode = curcode lastbiditype = curbiditype lastcombtype = curcombtype -if lastbiditype != "L" or lastcombtype != 0: - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d},\n" \ - % (begincode, lastcode, lastbiditype, lastcombtype))) -outfile.write ("{0, 0, 0, 0},\n") + lastmirrortype = curmirrortype +if lastbiditype != "L" or lastcombtype != 0 or lastmirrortype: + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d},\n" \ + % (begincode, lastcode, lastbiditype, lastcombtype, \ + lastmirrortype))) +outfile.write ("{0, 0, 0, 0, 0},\n") outfile.write ("};") From 82c5d8dcfce2ee144f55120c0f10f1d525c376e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Jan 2010 00:46:42 +0100 Subject: [PATCH 014/503] Support for 3 more combining marks types --- .bzrignore | 1 + font/font.c | 249 ++++++++++++++++++++++++----------------- include/grub/unicode.h | 3 + 3 files changed, 149 insertions(+), 104 deletions(-) diff --git a/.bzrignore b/.bzrignore index 8cdc9d12d..d313d0358 100644 --- a/.bzrignore +++ b/.bzrignore @@ -63,3 +63,4 @@ stamp-h1 stamp-h.in symlist.c update-grub_lib +unidata.c diff --git a/font/font.c b/font/font.c index 6655a29ae..172653c92 100644 --- a/font/font.c +++ b/font/font.c @@ -1163,6 +1163,21 @@ grub_font_construct_glyph (grub_font_t hinted_font, combtype = get_comb_type (glyph_id->combining[i]); switch (combtype) { + case GRUB_UNICODE_COMB_OVERLAY: + if (height < combining_glyphs[i]->height) + { + offset_y -= (combining_glyphs[i]->height - height) / 2; + height = combining_glyphs[i]->height; + } + if (width < combining_glyphs[i]->width) + { + offset_x -= (combining_glyphs[i]->width - width) / 2; + width = combining_glyphs[i]->width; + } + if (device_width < combining_glyphs[i]->width) + device_width = combining_glyphs[i]->width; + break; + case GRUB_UNICODE_STACK_ABOVE: { grub_int16_t space; @@ -1261,40 +1276,45 @@ grub_font_construct_glyph (grub_font_t hinted_font, for (i = 0; i < glyph_id->ncomb; i++) { enum grub_comb_type combtype; + grub_int16_t space = 0; + if (!combining_glyphs[i]) continue; combtype = get_comb_type (glyph_id->combining[i]); switch (combtype) { - case GRUB_UNICODE_STACK_ABOVE: - { - grub_int16_t space; - space = combining_glyphs[i]->offset_y - - grub_font_get_xheight (combining_glyphs[i]->font); - if (space < 0) - space = 1; + case GRUB_UNICODE_COMB_OVERLAY: + grub_font_blit_glyph (glyph, combining_glyphs[i], + (width - combining_glyphs[i]->width) / 2, + (height - combining_glyphs[i]->height) / 2); + break; - curtop += combining_glyphs[i]->height + space; - grub_font_blit_glyph (glyph, combining_glyphs[i], - (width - combining_glyphs[i]->width) / 2, - (height + offset_y) - curtop); - } + case GRUB_UNICODE_STACK_ABOVE: + space = combining_glyphs[i]->offset_y + - grub_font_get_xheight (combining_glyphs[i]->font); + if (space < 0) + space = 1; + + case GRUB_UNICODE_STACK_ATTACHED_ABOVE: + + curtop += combining_glyphs[i]->height + space; + grub_font_blit_glyph (glyph, combining_glyphs[i], + (width - combining_glyphs[i]->width) / 2, + (height + offset_y) - curtop); break; case GRUB_UNICODE_STACK_BELOW: - { - grub_int16_t space; - space = -(combining_glyphs[i]->offset_y - + combining_glyphs[i]->height); - if (space < 0) - space = 1; - - curbottom -= space; - grub_font_blit_glyph (glyph, combining_glyphs[i], - (width - combining_glyphs[i]->width) / 2, - (height + offset_y) - curbottom); - curbottom -= combining_glyphs[i]->height; - } + space = -(combining_glyphs[i]->offset_y + + combining_glyphs[i]->height); + if (space < 0) + space = 1; + + case GRUB_UNICODE_STACK_ATTACHED_BELOW: + curbottom -= space; + grub_font_blit_glyph (glyph, combining_glyphs[i], + (width - combining_glyphs[i]->width) / 2, + (height + offset_y) - curbottom); + curbottom -= combining_glyphs[i]->height; break; default: @@ -1525,87 +1545,107 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, cur_level = base_level; cur_override = OVERRIDE_NEUTRAL; - for (i = 0; i < logical_len; i++) - { - /* Variation selectors >= 17 are outside of BMP and SMP. - Handle variation selectors first to avoid potentially costly lookups. - */ - if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1 - && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16) - { - if (!visual_len) - continue; - visual[visual_len - 1].variant - = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1; - } - if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17 - && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256) - { - if (!visual_len) - continue; - visual[visual_len - 1].variant - = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17; - continue; - } - - type = get_bidi_type (logical[i]); - switch (type) - { - case GRUB_BIDI_TYPE_RLE: - push_stack (cur_override, (cur_level | 1) + 1); - break; - case GRUB_BIDI_TYPE_RLO: - push_stack (OVERRIDE_R, (cur_level | 1) + 1); - break; - case GRUB_BIDI_TYPE_LRE: - push_stack (cur_override, (cur_level & ~1) + 2); - break; - case GRUB_BIDI_TYPE_LRO: - push_stack (OVERRIDE_L, (cur_level & ~1) + 2); - break; - case GRUB_BIDI_TYPE_PDF: - pop_stack (); - break; - case GRUB_BIDI_TYPE_BN: - break; - default: + { + unsigned last_comb_pointer = 0; + for (i = 0; i < logical_len; i++) + { + /* Variation selectors >= 17 are outside of BMP and SMP. + Handle variation selectors first to avoid potentially costly lookups. + */ + if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1 + && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16) { - enum grub_comb_type comb_type; - comb_type = get_comb_type (logical[i]); - if (comb_type) - { - grub_uint32_t *n; - if (!visual_len) - break; - n = grub_realloc (visual[visual_len - 1].combining, - sizeof (grub_uint32_t) - * (visual[visual_len - 1].ncomb + 1)); - if (!n) - { - grub_errno = GRUB_ERR_NONE; - break; - } - visual[visual_len - 1].combining = n; - visual[visual_len - 1].combining[visual[visual_len - 1].ncomb] - = logical[i]; - visual[visual_len - 1].ncomb++; - break; - } - levels[visual_len] = cur_level; - if (cur_override != OVERRIDE_NEUTRAL) - resolved_types[visual_len] = - (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L : GRUB_BIDI_TYPE_R; - else - resolved_types[visual_len] = type; - visual[visual_len].base = logical[i]; - visual[visual_len].variant = 0; - visual[visual_len].attributes = 0; - visual[visual_len].ncomb = 0; - visual[visual_len].combining = NULL; - visual_len++; + if (!visual_len) + continue; + visual[visual_len - 1].variant + = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1; } - } - } + if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17 + && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256) + { + if (!visual_len) + continue; + visual[visual_len - 1].variant + = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17; + continue; + } + + type = get_bidi_type (logical[i]); + switch (type) + { + case GRUB_BIDI_TYPE_RLE: + push_stack (cur_override, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_RLO: + push_stack (OVERRIDE_R, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_LRE: + push_stack (cur_override, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_LRO: + push_stack (OVERRIDE_L, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_PDF: + pop_stack (); + break; + case GRUB_BIDI_TYPE_BN: + break; + default: + { + enum grub_comb_type comb_type; + comb_type = get_comb_type (logical[i]); + if (comb_type) + { + grub_uint32_t *n; + unsigned j; + + if (!visual_len) + break; + if (comb_type == GRUB_UNICODE_COMB_MC + || comb_type == GRUB_UNICODE_COMB_ME + || comb_type == GRUB_UNICODE_COMB_MN) + last_comb_pointer = visual[visual_len - 1].ncomb; + n = grub_realloc (visual[visual_len - 1].combining, + sizeof (grub_uint32_t) + * (visual[visual_len - 1].ncomb + 1)); + if (!n) + { + grub_errno = GRUB_ERR_NONE; + break; + } + + for (j = last_comb_pointer; + j < visual[visual_len - 1].ncomb; j++) + if (get_comb_type (visual[visual_len - 1].combining[j]) + > comb_type) + break; + grub_memmove (visual[visual_len - 1].combining + j + 1, + visual[visual_len - 1].combining + j, + (visual[visual_len - 1].ncomb - j) + * sizeof (visual[visual_len - 1].combining[0])); + visual[visual_len - 1].combining = n; + visual[visual_len - 1].combining[j] = logical[i]; + visual[visual_len - 1].ncomb++; + break; + } + last_comb_pointer = 0; + levels[visual_len] = cur_level; + if (cur_override != OVERRIDE_NEUTRAL) + resolved_types[visual_len] = + (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L + : GRUB_BIDI_TYPE_R; + else + resolved_types[visual_len] = type; + visual[visual_len].base = logical[i]; + visual[visual_len].variant = 0; + visual[visual_len].attributes = 0; + visual[visual_len].ncomb = 0; + visual[visual_len].combining = NULL; + visual_len++; + } + } + } + } for (run_start = 0; run_start < visual_len; run_start = run_end) { @@ -1781,6 +1821,7 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical, if (levels[i] < min_odd_level && (levels[i] & 1)) min_odd_level = levels[i]; } + /* FIXME: can be optimized. */ for (j = max_level; j >= min_odd_level; j--) { unsigned in = 0; diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 20c7c4167..17932a4b1 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -55,6 +55,9 @@ enum grub_bidi_type enum grub_comb_type { + GRUB_UNICODE_COMB_OVERLAY = 1, + GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, + GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, GRUB_UNICODE_STACK_BELOW = 220, GRUB_UNICODE_STACK_ABOVE = 230, /* If combining nature is indicated only by class and From 4361ca1c37370766de26933b657570d654509686 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Jan 2010 18:48:41 +0100 Subject: [PATCH 015/503] Restructure rendering to make extensions easier --- font/font.c | 306 ++++++++++++++++++----------------------- include/grub/unicode.h | 4 + include/grub/video.h | 9 ++ 3 files changed, 146 insertions(+), 173 deletions(-) diff --git a/font/font.c b/font/font.c index 172653c92..69dae08a0 100644 --- a/font/font.c +++ b/font/font.c @@ -1111,20 +1111,129 @@ get_comb_type (grub_uint32_t c) return GRUB_BIDI_TYPE_L; } +static void +blit_comb (const struct grub_unicode_glyph *glyph_id, + struct grub_font_glyph *glyph, + struct grub_video_signed_rect *bounds_out, + struct grub_font_glyph *main_glyph, + struct grub_font_glyph **combining_glyphs) +{ + struct grub_video_signed_rect bounds; + unsigned i; + auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, + signed dx, signed dy); + void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, + signed dx, signed dy) + { + if (glyph) + grub_font_blit_glyph (glyph, src, dx - glyph->offset_x, + (glyph->height + glyph->offset_y) + dy); + if (dx < bounds.x) + { + bounds.width += bounds.x - dx; + bounds.x = dx; + } + if (bounds.y > -src->height - dy) + { + bounds.height += bounds.y - (-src->height - dy); + bounds.y = (-src->height - dy); + } + if (dx + src->width - bounds.x >= (signed) bounds.width) + bounds.width = dx + src->width - bounds.x + 1; + if ((signed) bounds.height < src->height + (-src->height - dy) - bounds.y) + bounds.height = src->height + (-src->height - dy) - bounds.y; + } + + auto void minimal_device_width (int val); + void minimal_device_width (int val) + { + if (glyph && glyph->device_width < val) + glyph->device_width = val; + } + auto void add_device_width (int val); + void add_device_width (int val) + { + if (glyph) + glyph->device_width += val; + } + + bounds.x = main_glyph->offset_x; + bounds.y = main_glyph->offset_y; + bounds.width = main_glyph->width; + bounds.height = main_glyph->height; + + for (i = 0; i < glyph_id->ncomb; i++) + { + enum grub_comb_type combtype; + grub_int16_t space = 0; + grub_int16_t centerx = (bounds.width - combining_glyphs[i]->width) / 2 + + bounds.x; + + if (!combining_glyphs[i]) + continue; + combtype = get_comb_type (glyph_id->combining[i]); + switch (combtype) + { + case GRUB_UNICODE_COMB_OVERLAY: + do_blit (combining_glyphs[i], + centerx, + (bounds.height - combining_glyphs[i]->height) / 2 + -(bounds.height + bounds.y)); + minimal_device_width (combining_glyphs[i]->width); + break; + + case GRUB_UNICODE_STACK_ABOVE: + space = combining_glyphs[i]->offset_y + - grub_font_get_xheight (combining_glyphs[i]->font); + if (space < 0) + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + + case GRUB_UNICODE_STACK_ATTACHED_ABOVE: + do_blit (combining_glyphs[i], centerx, + -(bounds.height + bounds.y + space + + combining_glyphs[i]->height)); + minimal_device_width (combining_glyphs[i]->width); + break; + + case GRUB_UNICODE_STACK_BELOW: + space = -(combining_glyphs[i]->offset_y + + combining_glyphs[i]->height); + if (space < 0) + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + + case GRUB_UNICODE_STACK_ATTACHED_BELOW: + do_blit (combining_glyphs[i], centerx, + -(bounds.y - space)); + minimal_device_width (combining_glyphs[i]->width); + break; + + default: + { + /* Default handling. Just draw combining character on top + of base character. + FIXME: support more unicode types correctly. + */ + do_blit (combining_glyphs[i], + main_glyph->device_width + + combining_glyphs[i]->offset_x, + - (combining_glyphs[i]->height + + combining_glyphs[i]->offset_y)); + add_device_width (combining_glyphs[i]->device_width); + } + } + } + if (bounds_out) + *bounds_out = bounds; +} + static struct grub_font_glyph * grub_font_construct_glyph (grub_font_t hinted_font, const struct grub_unicode_glyph *glyph_id) { grub_font_t font; - grub_uint16_t width; - grub_uint16_t height; - grub_int16_t offset_x; - grub_int16_t offset_y; - grub_int16_t curtop, curbottom; - grub_uint16_t device_width; + struct grub_video_signed_rect bounds; struct grub_font_glyph *main_glyph; struct grub_font_glyph **combining_glyphs; - unsigned i; struct grub_font_glyph *glyph; main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base); @@ -1147,106 +1256,17 @@ grub_font_construct_glyph (grub_font_t hinted_font, } font = main_glyph->font; - width = main_glyph->width; - height = main_glyph->height; - offset_x = main_glyph->offset_x; - offset_y = main_glyph->offset_y; - device_width = main_glyph->device_width; - for (i = 0; i < glyph_id->ncomb; i++) - { - enum grub_comb_type combtype; + { + unsigned i; + for (i = 0; i < glyph_id->ncomb; i++) combining_glyphs[i] = grub_font_get_glyph_with_fallback (font, glyph_id->combining[i]); - if (!combining_glyphs[i]) - continue; - combtype = get_comb_type (glyph_id->combining[i]); - switch (combtype) - { - case GRUB_UNICODE_COMB_OVERLAY: - if (height < combining_glyphs[i]->height) - { - offset_y -= (combining_glyphs[i]->height - height) / 2; - height = combining_glyphs[i]->height; - } - if (width < combining_glyphs[i]->width) - { - offset_x -= (combining_glyphs[i]->width - width) / 2; - width = combining_glyphs[i]->width; - } - if (device_width < combining_glyphs[i]->width) - device_width = combining_glyphs[i]->width; - break; + } - case GRUB_UNICODE_STACK_ABOVE: - { - grub_int16_t space; - space = combining_glyphs[i]->offset_y - - grub_font_get_xheight (combining_glyphs[i]->font); - if (space < 1) - space = 1; - if (width < combining_glyphs[i]->width) - { - offset_x -= (combining_glyphs[i]->width - width) / 2; - width = combining_glyphs[i]->width; - } - if (device_width < combining_glyphs[i]->width) - device_width = combining_glyphs[i]->width; - height += combining_glyphs[i]->height + space; - } - break; + blit_comb (glyph_id, NULL, &bounds, main_glyph, combining_glyphs); - case GRUB_UNICODE_STACK_BELOW: - { - grub_int16_t space; - space = -(combining_glyphs[i]->offset_y - + combining_glyphs[i]->height); - if (space < 1) - space = 1; - if (width < combining_glyphs[i]->width) - { - offset_x -= (combining_glyphs[i]->width - width) / 2; - width = combining_glyphs[i]->width; - } - if (device_width < combining_glyphs[i]->width) - device_width = combining_glyphs[i]->width; - height += combining_glyphs[i]->height + space; - offset_y -= combining_glyphs[i]->height + space; - } - break; - - default: - { - /* Default handling. Just draw combining character on top - of base character. - FIXME: support more unicode types correctly. - */ - grub_int16_t nx = main_glyph->device_width - + combining_glyphs[i]->offset_x; - - device_width += combining_glyphs[i]->device_width; - if (nx < offset_x) - { - width += offset_x - nx; - offset_x = nx; - } - if (offset_y > combining_glyphs[i]->offset_y) - { - height += offset_y - combining_glyphs[i]->offset_y; - offset_y = combining_glyphs[i]->offset_y; - } - if (nx + combining_glyphs[i]->width - offset_x >= width) - width = nx + combining_glyphs[i]->width - offset_x + 1; - if (height - < (combining_glyphs[i]->height - + combining_glyphs[i]->offset_y) - offset_y) - height = (combining_glyphs[i]->height - + combining_glyphs[i]->offset_y) - offset_y; - } - } - } - - glyph = grub_zalloc (sizeof (*glyph) + (width * height + 7) / 8); + glyph = grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8); if (!glyph) { grub_errno = GRUB_ERR_NONE; @@ -1254,84 +1274,24 @@ grub_font_construct_glyph (grub_font_t hinted_font, } glyph->font = font; - glyph->width = width; - glyph->height = height; - glyph->offset_x = offset_x; - glyph->offset_y = offset_y; - glyph->device_width = device_width; + glyph->width = bounds.width; + glyph->height = bounds.height; + glyph->offset_x = bounds.x; + glyph->offset_y = bounds.y; + glyph->device_width = main_glyph->device_width; if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) grub_font_blit_glyph_mirror (glyph, main_glyph, - main_glyph->offset_x - offset_x, - (height + offset_y) + main_glyph->offset_x - glyph->offset_x, + (glyph->height + glyph->offset_y) - (main_glyph->height + main_glyph->offset_y)); else - grub_font_blit_glyph (glyph, main_glyph, main_glyph->offset_x - offset_x, - (height + offset_y) + grub_font_blit_glyph (glyph, main_glyph, + main_glyph->offset_x - glyph->offset_x, + (glyph->height + glyph->offset_y) - (main_glyph->height + main_glyph->offset_y)); - curtop = main_glyph->height + main_glyph->offset_y; - curbottom = main_glyph->offset_y; - - for (i = 0; i < glyph_id->ncomb; i++) - { - enum grub_comb_type combtype; - grub_int16_t space = 0; - - if (!combining_glyphs[i]) - continue; - combtype = get_comb_type (glyph_id->combining[i]); - switch (combtype) - { - case GRUB_UNICODE_COMB_OVERLAY: - grub_font_blit_glyph (glyph, combining_glyphs[i], - (width - combining_glyphs[i]->width) / 2, - (height - combining_glyphs[i]->height) / 2); - break; - - case GRUB_UNICODE_STACK_ABOVE: - space = combining_glyphs[i]->offset_y - - grub_font_get_xheight (combining_glyphs[i]->font); - if (space < 0) - space = 1; - - case GRUB_UNICODE_STACK_ATTACHED_ABOVE: - - curtop += combining_glyphs[i]->height + space; - grub_font_blit_glyph (glyph, combining_glyphs[i], - (width - combining_glyphs[i]->width) / 2, - (height + offset_y) - curtop); - break; - - case GRUB_UNICODE_STACK_BELOW: - space = -(combining_glyphs[i]->offset_y - + combining_glyphs[i]->height); - if (space < 0) - space = 1; - - case GRUB_UNICODE_STACK_ATTACHED_BELOW: - curbottom -= space; - grub_font_blit_glyph (glyph, combining_glyphs[i], - (width - combining_glyphs[i]->width) / 2, - (height + offset_y) - curbottom); - curbottom -= combining_glyphs[i]->height; - break; - - default: - { - /* Default handling. Just draw combining character on top - of base character. - FIXME: support more unicode types correctly. - */ - grub_font_blit_glyph (glyph, combining_glyphs[i], - main_glyph->device_width - + combining_glyphs[i]->offset_x - offset_x, - (height + offset_y) - - (combining_glyphs[i]->height - + combining_glyphs[i]->offset_y)); - } - } - } + blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs); return glyph; } diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 17932a4b1..6e455394d 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -57,9 +57,13 @@ enum grub_comb_type { GRUB_UNICODE_COMB_OVERLAY = 1, GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, + GRUB_UNICODE_COMB_ATTACHED_BELOW_RIGHT = 204, GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, + GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, GRUB_UNICODE_STACK_BELOW = 220, + GRUB_UNICODE_COMB_BELOW_RIGHT = 222, GRUB_UNICODE_STACK_ABOVE = 230, + GRUB_UNICODE_COMB_ABOVE_RIGHT = 232, /* If combining nature is indicated only by class and not "combining type". */ GRUB_UNICODE_COMB_ME = 253, diff --git a/include/grub/video.h b/include/grub/video.h index 868e87871..0546706e4 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -167,6 +167,15 @@ struct grub_video_rect }; typedef struct grub_video_rect grub_video_rect_t; +struct grub_video_signed_rect +{ + signed x; + signed y; + unsigned width; + unsigned height; +}; +typedef struct grub_video_signed_rect grub_video_signed_rect_t; + struct grub_video_palette_data { grub_uint8_t r; /* Red color value (0-255). */ From 7181e2281f559317133fa9e3c5924451872061fd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 25 Jan 2010 17:47:51 +0000 Subject: [PATCH 016/503] 2010-01-25 Colin Watson * configure.ac: Check for Linux device-mapper support. * util/hostdisk.c (device_is_mapped): New function. (find_partition_start): New function, partly broken out from linux_find_partition and grub_util_biosdisk_get_grub_dev but with device-mapper support added. (linux_find_partition): Use find_partition_start. (convert_system_partition_to_system_disk): Add `st' argument. Support Linux /dev/mapper/* devices if device-mapper support is available; only DM-RAID devices are understood at present. (find_system_device): Add `st' argument. Pass it to convert_system_partition_to_system_disk. (grub_util_biosdisk_get_grub_dev): Pass stat result to find_system_device and convert_system_partition_to_system_disk. Use find_partition_start. --- ChangeLog.dmraid-probe | 16 +++ configure.ac | 17 +++ util/hostdisk.c | 243 +++++++++++++++++++++++++++++++++++------ 3 files changed, 242 insertions(+), 34 deletions(-) create mode 100644 ChangeLog.dmraid-probe diff --git a/ChangeLog.dmraid-probe b/ChangeLog.dmraid-probe new file mode 100644 index 000000000..8b8f25533 --- /dev/null +++ b/ChangeLog.dmraid-probe @@ -0,0 +1,16 @@ +2010-01-25 Colin Watson + + * configure.ac: Check for Linux device-mapper support. + * util/hostdisk.c (device_is_mapped): New function. + (find_partition_start): New function, partly broken out from + linux_find_partition and grub_util_biosdisk_get_grub_dev but with + device-mapper support added. + (linux_find_partition): Use find_partition_start. + (convert_system_partition_to_system_disk): Add `st' argument. + Support Linux /dev/mapper/* devices if device-mapper support is + available; only DM-RAID devices are understood at present. + (find_system_device): Add `st' argument. Pass it to + convert_system_partition_to_system_disk. + (grub_util_biosdisk_get_grub_dev): Pass stat result to + find_system_device and convert_system_partition_to_system_disk. Use + find_partition_start. diff --git a/configure.ac b/configure.ac index be498be8b..4f1a6dffe 100644 --- a/configure.ac +++ b/configure.ac @@ -659,6 +659,23 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) +AC_ARG_ENABLE([device-mapper], + [AS_HELP_STRING([--enable-device-mapper], + [enable Linux device-mapper support (default=guessed)])]) +if test x"$enable_device_mapper" = xno ; then + device_mapper_excuse="explicitly disabled" +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_task_create], + [LDFLAGS="$LDFLAGS -ldevmapper" + AC_DEFINE([HAVE_DEVICE_MAPPER], [1], + [Define to 1 if you have the devmapper library.])], + [device_mapper_excuse="need devmapper library"]) + AC_SUBST([LIBDEVMAPPER]) +fi + AC_SUBST(ASFLAGS) # Output files. diff --git a/util/hostdisk.c b/util/hostdisk.c index a594f75ec..309e112bf 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -97,6 +97,10 @@ struct hd_geometry # include #endif +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + struct { char *drive; @@ -253,6 +257,115 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) return GRUB_ERR_NONE; } +#ifdef HAVE_DEVICE_MAPPER +static int +device_is_mapped (const char *dev) +{ + struct stat st; + + if (stat (dev, &st) < 0) + return 0; + + return dm_is_dm_major (major (st.st_rdev)); +} +#endif /* HAVE_DEVICE_MAPPER */ + +#if defined(__linux__) || defined(__CYGWIN__) +static grub_disk_addr_t +find_partition_start (const char *dev) +{ + int fd; + struct hd_geometry hdg; + +#ifdef HAVE_DEVICE_MAPPER + if (device_is_mapped (dev)) { + struct dm_task *task = NULL; + grub_uint64_t start, length; + char *target_type, *params, *space; + grub_disk_addr_t partition_start; + + /* If any device-mapper operation fails, we fall back silently to + HDIO_GETGEO. */ + task = dm_task_create (DM_DEVICE_TABLE); + if (! task) + { + grub_dprintf ("hostdisk", "dm_task_create failed\n"); + goto devmapper_fail; + } + + if (! dm_task_set_name (task, dev)) + { + grub_dprintf ("hostdisk", "dm_task_set_name failed\n"); + goto devmapper_fail; + } + + if (! dm_task_run (task)) + { + grub_dprintf ("hostdisk", "dm_task_run failed\n"); + goto devmapper_fail; + } + + dm_get_next_target (task, NULL, &start, &length, &target_type, ¶ms); + if (! target_type) + { + grub_dprintf ("hostdisk", "no dm target\n"); + goto devmapper_fail; + } + if (strcmp (target_type, "linear") != 0) + { + grub_dprintf ("hostdisk", "ignoring dm target %s (not linear)\n", + target_type); + goto devmapper_fail; + } + if (! params) + { + grub_dprintf ("hostdisk", "no dm params\n"); + goto devmapper_fail; + } + + /* The params string for a linear target looks like this: + DEVICE-NAME START-SECTOR + Parse this out. */ + space = strchr (params, ' '); + if (! space) + goto devmapper_fail; + errno = 0; + partition_start = strtoull (space + 1, NULL, 10); + if (errno == 0) + { + grub_dprintf ("hostdisk", "dm %s starts at %llu\n", + dev, partition_start); + dm_task_destroy (task); + return partition_start; + } + +devmapper_fail: + if (task) + dm_task_destroy (task); + } +#endif /* HAVE_DEVICE_MAPPER */ + + fd = open (dev, O_RDONLY); + if (fd == -1) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); + return 0; + } + + if (ioctl (fd, HDIO_GETGEO, &hdg)) + { + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot get geometry of `%s'", dev); + close (fd); + return 0; + } + + close (fd); + + return hdg.start; +} +#endif /* __linux__ || __CYGWIN__ */ + #ifdef __linux__ static int linux_find_partition (char *dev, unsigned long sector) @@ -284,22 +397,20 @@ linux_find_partition (char *dev, unsigned long sector) for (i = 1; i < 10000; i++) { int fd; - struct hd_geometry hdg; + grub_disk_addr_t start; 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) + start = find_partition_start (real_dev); + /* We don't care about errors here. */ + grub_errno = GRUB_ERR_NONE; + + if (start == sector) { strcpy (dev, real_dev); return 1; @@ -699,7 +810,7 @@ make_device_name (int drive, int dos_part, int bsd_part) } static char * -convert_system_partition_to_system_disk (const char *os_dev) +convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) { #if defined(__linux__) char *path = xmalloc (PATH_MAX); @@ -817,6 +928,83 @@ convert_system_partition_to_system_disk (const char *os_dev) p[4] = '\0'; return path; } + +#ifdef HAVE_DEVICE_MAPPER + /* If this is a DM-RAID device. */ + if ((strncmp ("mapper/", p, 7) == 0)) + { + static struct dm_tree *tree = NULL; + uint32_t maj, min; + struct dm_tree_node *node, *child; + void *handle; + const char *node_uuid, *child_uuid, *child_name; + + if (! tree) + tree = dm_tree_create (); + + if (! tree) + { + grub_dprintf ("hostdisk", "dm_tree_create failed\n"); + return NULL; + } + + maj = major (st->st_rdev); + min = minor (st->st_rdev); + if (! dm_tree_add_dev (tree, maj, min)) + { + grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); + return NULL; + } + + node = dm_tree_find_node (tree, maj, min); + if (! node) + { + grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); + return NULL; + } + node_uuid = dm_tree_node_get_uuid (node); + if (! node_uuid) + { + grub_dprintf ("hostdisk", "%s has no DM uuid\n", path); + return NULL; + } + else if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); + return NULL; + } + + handle = NULL; + /* Counter-intuitively, device-mapper refers to the disk-like + device containing a DM-RAID partition device as a "child" of + the partition device. */ + child = dm_tree_next_child (&handle, node, 0); + if (! child) + { + grub_dprintf ("hostdisk", "%s has no DM children\n", path); + return NULL; + } + child_uuid = dm_tree_node_get_uuid (child); + if (! child_uuid) + { + grub_dprintf ("hostdisk", "%s child has no DM uuid\n", path); + return NULL; + } + else if (strncmp (child_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); + return NULL; + } + child_name = dm_tree_node_get_name (child); + if (! child_name) + { + grub_dprintf ("hostdisk", "%s child has no DM name\n", path); + return NULL; + } + + return xasprintf ("/dev/mapper/%s", child_name); + } +#endif /* HAVE_DEVICE_MAPPER */ } return path; @@ -872,12 +1060,12 @@ device_is_wholedisk (const char *os_dev) #endif static int -find_system_device (const char *os_dev) +find_system_device (const char *os_dev, struct stat *st) { unsigned int i; char *os_disk; - os_disk = convert_system_partition_to_system_disk (os_dev); + os_disk = convert_system_partition_to_system_disk (os_dev, st); if (! os_disk) return -1; @@ -911,7 +1099,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - drive = find_system_device (os_dev); + drive = find_system_device (os_dev, &st); if (drive < 0) { grub_error (GRUB_ERR_BAD_DEVICE, @@ -919,8 +1107,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev)) - == 0) + if (grub_strcmp (os_dev, + convert_system_partition_to_system_disk (os_dev, &st)) == 0) return make_device_name (drive, -1, -1); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) @@ -942,8 +1130,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) { char *name; grub_disk_t disk; - int fd; - struct hd_geometry hdg; + grub_disk_addr_t start; int dos_part = -1; int bsd_part = -1; auto int find_partition (grub_disk_t disk, @@ -973,7 +1160,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) partition->index, partition->start); } - if (hdg.start == partition->start) + if (start == partition->start) { if (pcdata) { @@ -996,28 +1183,16 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) return name; - fd = open (os_dev, O_RDONLY); - if (fd == -1) + start = find_partition_start (os_dev); + if (grub_errno != GRUB_ERR_NONE) { - 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; - } + grub_util_info ("%s starts from %lu", os_dev, start); - close (fd); - - grub_util_info ("%s starts from %lu", os_dev, hdg.start); - - if (hdg.start == 0 && device_is_wholedisk (os_dev)) + if (start == 0 && device_is_wholedisk (os_dev)) return name; grub_util_info ("opening the device %s", name); From b769a37b6ea0593c865e8a3ec501dd03757e44eb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 26 Jan 2010 14:26:16 +0000 Subject: [PATCH 017/503] 2010-01-26 Colin Watson * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, kern/err.c, kern/list.c, and kern/misc.c. * util/deviceiter.c [__linux__]: Define MINOR. (grub_util_iterate_devices): Add support for DM-RAID disk devices. * util/mkdevicemap.c (grub_putchar): New function. (grub_getkey): New function. (grub_refresh): New function. (main): Set debug=all if -v -v is used. --- ChangeLog.dmraid-probe | 12 +++- conf/common.rmk | 3 +- util/deviceiter.c | 140 ++++++++++++++++++++++++++++++++++++++++ util/grub-mkdevicemap.c | 22 +++++++ 4 files changed, 175 insertions(+), 2 deletions(-) diff --git a/ChangeLog.dmraid-probe b/ChangeLog.dmraid-probe index 8b8f25533..505cf7ba4 100644 --- a/ChangeLog.dmraid-probe +++ b/ChangeLog.dmraid-probe @@ -1,6 +1,7 @@ -2010-01-25 Colin Watson +2010-01-26 Colin Watson * configure.ac: Check for Linux device-mapper support. + * util/hostdisk.c (device_is_mapped): New function. (find_partition_start): New function, partly broken out from linux_find_partition and grub_util_biosdisk_get_grub_dev but with @@ -14,3 +15,12 @@ (grub_util_biosdisk_get_grub_dev): Pass stat result to find_system_device and convert_system_partition_to_system_disk. Use find_partition_start. + + * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, + kern/err.c, kern/list.c, and kern/misc.c. + * util/deviceiter.c [__linux__]: Define MINOR. + (grub_util_iterate_devices): Add support for DM-RAID disk devices. + * util/mkdevicemap.c (grub_putchar): New function. + (grub_getkey): New function. + (grub_refresh): New function. + (main): Set debug=all if -v -v is used. diff --git a/conf/common.rmk b/conf/common.rmk index 2ea8ebd5a..94a96a313 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -3,7 +3,8 @@ sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ - util/misc.c + util/misc.c \ + kern/env.c kern/err.c kern/list.c kern/misc.c ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c diff --git a/util/deviceiter.c b/util/deviceiter.c index b0a9e1388..03813bc7d 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -31,6 +31,8 @@ #include #include +#include +#include #ifdef __linux__ # if !defined(__GLIBC__) || \ @@ -62,12 +64,23 @@ struct hd_geometry | ((unsigned int) (__dev >> 32) & ~0xfff); \ }) # endif /* ! MAJOR */ +# ifndef MINOR +# define MINOR(dev) \ + ({ \ + unsigned long long __dev = (dev); \ + (unsigned) (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); \ + }) +# endif /* ! MINOR */ # 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 */ + +#ifdef HAVE_DEVICE_MAPPER +# include +#endif #endif /* __linux__ */ /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with @@ -411,6 +424,16 @@ check_device (const char *device) return 1; } +#ifdef __linux__ +# ifdef HAVE_DEVICE_MAPPER +struct dmraid_seen +{ + struct dmraid_seen *next; + const char *name; +}; +# endif /* HAVE_DEVICE_MAPPER */ +#endif /* __linux__ */ + void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), int floppy_disks) @@ -643,6 +666,123 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), return; } } + +# ifdef HAVE_DEVICE_MAPPER +# define dmraid_check(cond, ...) \ + if (! (cond)) \ + { \ + grub_dprintf ("deviceiter", __VA_ARGS__); \ + goto dmraid_end; \ + } + + /* DM-RAID. */ + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + struct dmraid_seen *seen = NULL; + + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (void *) names + next; + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); + + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + struct dmraid_seen *seen_elt; + + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } + + /* Have we already seen this node? There are typically very few + DM-RAID disks, so a list should be fast enough. */ + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) + { + grub_dprintf ("deviceiter", "Already seen DM device %s\n", + node_name); + goto dmraid_next_child; + } + + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device (name)) + { + if (hook (name, 0)) + { + free (name); + while (seen) + { + struct dmraid_seen *seen_elt = + grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + return; + } + } + free (name); + + seen_elt = xmalloc (sizeof *seen_elt); + seen_elt->name = node_name; + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + +dmraid_next_child: + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } + +dmraid_end: + while (seen) + { + struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } +# endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ } diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index c68482af1..db37f99e6 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -31,6 +31,7 @@ #include #include +#include #include #define _GNU_SOURCE 1 @@ -38,6 +39,24 @@ #include "progname.h" +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + static void make_device_map (const char *device_map, int floppy_disks) { @@ -158,6 +177,9 @@ main (int argc, char *argv[]) } } + if (verbosity > 1) + grub_env_set ("debug", "all"); + make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks); free (dev_map); From b9c4f55b6fb10c07d96c4dd983d3e58a4ba09504 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 31 Jan 2010 19:37:37 +0000 Subject: [PATCH 018/503] handle DM-RAID disks in convert_system_partition_to_system_disk --- ChangeLog.dmraid-probe | 2 +- util/hostdisk.c | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ChangeLog.dmraid-probe b/ChangeLog.dmraid-probe index 505cf7ba4..c52436bb5 100644 --- a/ChangeLog.dmraid-probe +++ b/ChangeLog.dmraid-probe @@ -1,4 +1,4 @@ -2010-01-26 Colin Watson +2010-01-31 Colin Watson * configure.ac: Check for Linux device-mapper support. diff --git a/util/hostdisk.c b/util/hostdisk.c index 309e112bf..464977978 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -937,7 +937,7 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) uint32_t maj, min; struct dm_tree_node *node, *child; void *handle; - const char *node_uuid, *child_uuid, *child_name; + const char *node_uuid, *mapper_name, *child_uuid, *child_name; if (! tree) tree = dm_tree_create (); @@ -975,6 +975,7 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) } handle = NULL; + mapper_name = NULL; /* Counter-intuitively, device-mapper refers to the disk-like device containing a DM-RAID partition device as a "child" of the partition device. */ @@ -982,27 +983,39 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) if (! child) { grub_dprintf ("hostdisk", "%s has no DM children\n", path); - return NULL; + goto devmapper_out; } child_uuid = dm_tree_node_get_uuid (child); if (! child_uuid) { grub_dprintf ("hostdisk", "%s child has no DM uuid\n", path); - return NULL; + goto devmapper_out; } else if (strncmp (child_uuid, "DMRAID-", 7) != 0) { grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); - return NULL; + goto devmapper_out; } child_name = dm_tree_node_get_name (child); if (! child_name) { grub_dprintf ("hostdisk", "%s child has no DM name\n", path); - return NULL; + goto devmapper_out; } + mapper_name = child_name; - return xasprintf ("/dev/mapper/%s", child_name); +devmapper_out: + if (! mapper_name) + { + /* This is a DM-RAID disk, not a partition. */ + mapper_name = dm_tree_node_get_name (node); + if (! mapper_name) + { + grub_dprintf ("hostdisk", "%s has no DM name\n", path); + return NULL; + } + } + return xasprintf ("/dev/mapper/%s", mapper_name); } #endif /* HAVE_DEVICE_MAPPER */ } From a800277e8d63dbab8de3f8bd2e8c56ad3e9d5778 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 5 Feb 2010 09:08:22 -0800 Subject: [PATCH 019/503] remove left-over LIBDEVMAPPER substitution --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4f1a6dffe..8e412f001 100644 --- a/configure.ac +++ b/configure.ac @@ -673,7 +673,6 @@ if test x"$device_mapper_excuse" = x ; then AC_DEFINE([HAVE_DEVICE_MAPPER], [1], [Define to 1 if you have the devmapper library.])], [device_mapper_excuse="need devmapper library"]) - AC_SUBST([LIBDEVMAPPER]) fi AC_SUBST(ASFLAGS) From 1c1261d985a938e7f525287fd8b50e78bbebeaaf Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 6 Feb 2010 14:29:42 +0530 Subject: [PATCH 020/503] fixed grub-install.in --- util/grub-install.in | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/util/grub-install.in b/util/grub-install.in index bb323d706..5016a2a17 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -105,7 +105,11 @@ EOF } # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -113,33 +117,62 @@ for option in "$@"; do -v | --version) echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; + + --modules) + modules=$1; shift;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; + + --font) + font=$1; shift;; --font=*) font=`echo "$option" | sed 's/--font=//'` ;; + + --root-directory) + rootdir=$1; shift;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + + --grub-setup) + grub_setup=$1; shift;; --grub-setup=*) grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;; + + --grub-mkimage) + grub_mkimage=$1; shift;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + + --grub-mkdevicemap) + grub_mkdevicemap=$1; shift;; --grub-mkdevicemap=*) grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + + --grub-probe) + grub_probe=$1; shift;; --grub-probe=*) grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + --no-floppy) no_floppy="--no-floppy" ;; --recheck) recheck=yes ;; + + --disk-module) + if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then + disk_module=$1; shift; + fi ;; --disk-module=*) if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then disk_module=`echo "$option" | sed 's/--disk-module=//'` fi ;; + # This is an undocumented feature... --debug) debug=yes ;; -f | --force) setup_force="--force" ;; + -*) echo "Unrecognized option \`$option'" 1>&2 usage From 7a64e28d0e1726f539041bc7562ff9498554f333 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 7 Feb 2010 10:14:50 +0530 Subject: [PATCH 021/503] fixed mkconfig and mkrescue scripts --- util/grub-mkconfig.in | 10 +++++++--- util/grub-mkrescue.in | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 49e52b313..34e46605c 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -50,7 +50,11 @@ EOF } # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -58,9 +62,9 @@ for option in "$@"; do -v | --version) echo "$0 (GNU GRUB ${package_version})" exit 0 ;; - -o) - shift + -o | --output) grub_cfg=$1 + shift ;; --output=*) grub_cfg=`echo "$option" | sed 's/--output=//'` diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 6b3c9ecb8..b9ef3219b 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -42,8 +42,8 @@ Make GRUB rescue image. -h, --help print this message and exit -v, --version print the version information and exit + -o, --output=FILE save output in FILE [required] --modules=MODULES pre-load specified modules MODULES - --output=FILE save output in FILE [required] $0 generates a bootable rescue image with specified source files or directories. @@ -52,7 +52,11 @@ EOF } # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -60,11 +64,24 @@ for option in "$@"; do -v | --version) echo "$0 (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; + + --modules) + modules=$1; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; + + -o | --output) + output_image=$1; shift ;; --output=*) output_image=`echo "$option" | sed 's/--output=//'` ;; + # Intentionally undocumented + --override-directory) + override_dir=$1 + shift + PATH=${override_dir}:$PATH + export PATH + ;; --override-directory=*) override_dir=`echo "${option}/" | sed 's/--override-directory=//'` PATH=${override_dir}:$PATH From 09f38ecd5a8dcd5e7cde3640e3355aaac766a5de Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 7 Feb 2010 10:31:04 +0530 Subject: [PATCH 022/503] fix remaining scripts --- util/grub-reboot.in | 10 +++++++++- util/grub-set-default.in | 10 +++++++++- util/i386/efi/grub-install.in | 22 +++++++++++++++++++++- util/ieee1275/grub-install.in | 22 +++++++++++++++++++++- util/powerpc/ieee1275/grub-mkrescue.in | 16 +++++++++++++++- 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/util/grub-reboot.in b/util/grub-reboot.in index 20f2b10bc..eb7073e02 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -45,7 +45,11 @@ EOF } # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -53,8 +57,12 @@ for option in "$@"; do -v | --version) echo "grub-reboot (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; + + --root-directory) + rootdir=$1; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + -*) echo "Unrecognized option \`$option'" 1>&2 usage diff --git a/util/grub-set-default.in b/util/grub-set-default.in index 4d7c10e8e..2636543c3 100644 --- a/util/grub-set-default.in +++ b/util/grub-set-default.in @@ -45,7 +45,11 @@ EOF } # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -53,8 +57,12 @@ for option in "$@"; do -v | --version) echo "grub-set-default (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; + + --root-directory) + rootdir=$1; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + -*) echo "Unrecognized option \`$option'" 1>&2 usage diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index caa7be7e4..b93525e3e 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -71,7 +71,11 @@ EOF } # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -79,16 +83,32 @@ for option in "$@"; do -v | --version) echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; + + --modules) + modules=$1; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; + + --root-directory) + rootdir=$1; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + + --grub-mkimage) + grub_mkimage=$1; shift ;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + + --grub-mkdevicemap) + grub_mkdevicemap=$1; shift ;; --grub-mkdevicemap=*) grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + + --grub-probe) + grub_probe=$1; shift ;; --grub-probe=*) grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + --no-floppy) no_floppy="--no-floppy" ;; --recheck) diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 97c485d55..63dde62b3 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -75,7 +75,11 @@ EOF } # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -83,16 +87,32 @@ for option in "$@"; do -v | --version) echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; + + --modules) + modules=$1; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; + + --root-directory) + rootdir=$1; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + + --grub-mkdevicemap) + grub_mkdevicemap=$1; shift ;; --grub-mkdevicemap=*) grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + + --grub-mkimage) + grub_mkimage=$1; shift ;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + + --grub-probe) + grub_probe=$1; shift ;; --grub-probe=*) grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + --no-nvram) update_nvram=no ;; # This is an undocumented feature... diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index 0110e799c..375adb0cb 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -55,7 +55,11 @@ EOF input_dir=${pkglibdir} # Check the arguments. -for option in "$@"; do +while test $# -gt 0 +do + option=$1 + shift + case "$option" in -h | --help) usage @@ -63,12 +67,22 @@ for option in "$@"; do -v | --version) echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; + + --modules) + modules=$1; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; + + --pkglibdir) + input_dir=$1; shift ;; --pkglibdir=*) input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;; + + --grub-mkimage) + grub_mkimage=$1; shift ;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + -*) echo "Unrecognized option \`$option'" 1>&2 usage From 09d708c68ac6ccee9a7550b9638faa08a1261ebd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 8 Feb 2010 00:38:09 +0100 Subject: [PATCH 023/503] Support above_right diacritics --- font/font.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/font/font.c b/font/font.c index 69dae08a0..ff64111a9 100644 --- a/font/font.c +++ b/font/font.c @@ -1120,6 +1120,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, { struct grub_video_signed_rect bounds; unsigned i; + signed above_rightx, above_righty; auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, signed dx, signed dy); void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, @@ -1162,6 +1163,9 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, bounds.width = main_glyph->width; bounds.height = main_glyph->height; + above_rightx = bounds.x + bounds.width; + above_righty = bounds.y + bounds.height; + for (i = 0; i < glyph_id->ncomb; i++) { enum grub_comb_type combtype; @@ -1182,6 +1186,14 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, minimal_device_width (combining_glyphs[i]->width); break; + case GRUB_UNICODE_COMB_ABOVE_RIGHT: + do_blit (combining_glyphs[i], above_rightx, + -(above_righty + space + + combining_glyphs[i]->height)); + above_rightx += combining_glyphs[i]->width; + minimal_device_width (above_rightx); + break; + case GRUB_UNICODE_STACK_ABOVE: space = combining_glyphs[i]->offset_y - grub_font_get_xheight (combining_glyphs[i]->font); From 0a71a0972ceac391185ac7f6b54f15a46cf1fef6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 8 Feb 2010 01:26:59 +0100 Subject: [PATCH 024/503] Type 216 --- font/font.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/font/font.c b/font/font.c index ff64111a9..5d307c0a1 100644 --- a/font/font.c +++ b/font/font.c @@ -1186,10 +1186,15 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, minimal_device_width (combining_glyphs[i]->width); break; + case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT: + do_blit (combining_glyphs[i], above_rightx, -above_righty); + above_rightx += combining_glyphs[i]->width; + minimal_device_width (above_rightx); + break; + case GRUB_UNICODE_COMB_ABOVE_RIGHT: do_blit (combining_glyphs[i], above_rightx, - -(above_righty + space - + combining_glyphs[i]->height)); + -(above_righty + combining_glyphs[i]->height)); above_rightx += combining_glyphs[i]->width; minimal_device_width (above_rightx); break; From 9d9dca02d9a4a99495c1e8b9121a3039172e05c5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 8 Feb 2010 01:44:06 +0100 Subject: [PATCH 025/503] Type 240 --- font/font.c | 2 ++ include/grub/unicode.h | 1 + 2 files changed, 3 insertions(+) diff --git a/font/font.c b/font/font.c index 5d307c0a1..5cda443e7 100644 --- a/font/font.c +++ b/font/font.c @@ -1212,6 +1212,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, minimal_device_width (combining_glyphs[i]->width); break; + /* I don't know how ypogegrammeni differs from subscript. */ + case GRUB_UNICODE_COMB_YPOGEGRAMMENI: case GRUB_UNICODE_STACK_BELOW: space = -(combining_glyphs[i]->offset_y + combining_glyphs[i]->height); diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 6e455394d..93f9f147d 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -64,6 +64,7 @@ enum grub_comb_type GRUB_UNICODE_COMB_BELOW_RIGHT = 222, GRUB_UNICODE_STACK_ABOVE = 230, GRUB_UNICODE_COMB_ABOVE_RIGHT = 232, + GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240, /* If combining nature is indicated only by class and not "combining type". */ GRUB_UNICODE_COMB_ME = 253, From 1876cfdb56719ddd65eed9e52c0e6ecfeea30a9e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 8 Feb 2010 02:01:10 +0100 Subject: [PATCH 026/503] GCJ --- font/font.c | 3 +++ include/grub/unicode.h | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/font/font.c b/font/font.c index 5cda443e7..fa619c4cd 100644 --- a/font/font.c +++ b/font/font.c @@ -1175,6 +1175,9 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, if (!combining_glyphs[i]) continue; + /* CGJ is to avoid diacritics reordering. */ + if (glyph_id->combining[i] == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) + continue; combtype = get_comb_type (glyph_id->combining[i]); switch (combtype) { diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 93f9f147d..59649c3b5 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -57,11 +57,9 @@ enum grub_comb_type { GRUB_UNICODE_COMB_OVERLAY = 1, GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, - GRUB_UNICODE_COMB_ATTACHED_BELOW_RIGHT = 204, GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, GRUB_UNICODE_STACK_BELOW = 220, - GRUB_UNICODE_COMB_BELOW_RIGHT = 222, GRUB_UNICODE_STACK_ABOVE = 230, GRUB_UNICODE_COMB_ABOVE_RIGHT = 232, GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240, @@ -83,6 +81,7 @@ struct grub_unicode_glyph }; #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 +#define GRUB_UNICODE_COMBINING_GRAPHEME_JOINER 0x34f #define GRUB_UNICODE_VARIATION_SELECTOR_1 0xfe00 #define GRUB_UNICODE_VARIATION_SELECTOR_16 0xfe0f #define GRUB_UNICODE_VARIATION_SELECTOR_17 0xe0100 From 232f7e29c95654932f3ad291dcb7194c27a45be4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Feb 2010 22:39:59 +0100 Subject: [PATCH 027/503] SMBus on CS5536 support --- bus/cs5536.c | 213 +++++++++++++++++++++++++++++++++ commands/mips/yeeloong/lsspd.c | 92 ++++++++++++++ conf/mips-yeeloong.rmk | 11 ++ disk/ata.c | 3 +- include/grub/cs5536.h | 62 ++++++++++ include/grub/smbus.h | 39 ++++++ 6 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 bus/cs5536.c create mode 100644 commands/mips/yeeloong/lsspd.c create mode 100644 include/grub/cs5536.h create mode 100644 include/grub/smbus.h diff --git a/bus/cs5536.c b/bus/cs5536.c new file mode 100644 index 000000000..3a7ac2bb1 --- /dev/null +++ b/bus/cs5536.c @@ -0,0 +1,213 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +int +grub_cs5536_find (grub_pci_device_t *devp) +{ + int found = 0; + auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid); + + int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid) + { + if (pciid == GRUB_CS5536_PCIID) + { + *devp = dev; + found = 1; + return 1; + } + return 0; + } + + grub_pci_iterate (hook); + + return found; +} + +grub_uint64_t +grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr) +{ + grub_uint64_t ret = 0; + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + ret = (grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0)); + ret |= (((grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, + GRUB_CS5536_MSR_MAILBOX_DATA1))) + << 32); + return ret; +} + +void +grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr, + grub_uint64_t val) +{ + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0), + val & 0xffffffff); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1), + val >> 32); +} + +grub_err_t +grub_cs5536_smbus_wait (grub_port_t smbbase) +{ + grub_uint64_t start = grub_get_time_ms (); + while (1) + { + grub_uint8_t status; + status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS); + if (status & (1 << 6)) + return GRUB_ERR_NONE; + if (status & (1 << 5)) + return grub_error (GRUB_ERR_IO, "SM bus error"); + if (status & (1 << 4)) + return grub_error (GRUB_ERR_IO, "NACK received"); + if (grub_get_time_ms () > start + 40) + return grub_error (GRUB_ERR_IO, "SM stalled"); + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res) +{ + grub_err_t err; + + /* Send START. */ + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send ACK. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_ACK, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send byte address. */ + grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send START. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb ((dev << 1) | 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send STOP. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_STOP, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + *res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, + grub_port_t *smbbase) +{ + grub_uint64_t smbbar; + + smbbar = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_SMB_BAR); + + /* FIXME */ + if (!(smbbar & GRUB_CS5536_LBAR_ENABLE)) + return grub_error(GRUB_ERR_IO, "SMB controller not enabled\n"); + *smbbase = (smbbar & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE; + + if (divisor < 8) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid divisor"); + + /* Disable SMB. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + /* Disable interrupts. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Set as master. */ + grub_outb (GRUB_CS5536_SMB_REG_ADDR_MASTER, + *smbbase + GRUB_CS5536_SMB_REG_ADDR); + + /* Launch. */ + grub_outb (((divisor >> 7) & 0xff), *smbbase + GRUB_CS5536_SMB_REG_CTRL3); + grub_outb (((divisor << 1) & 0xfe) | GRUB_CS5536_SMB_REG_CTRL2_ENABLE, + *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, + struct grub_smbus_spd *res) +{ + grub_err_t err; + grub_size_t size; + grub_uint8_t b; + grub_size_t ptr; + + err = grub_cs5536_read_spd_byte (smbbase, dev, 0, &b); + if (err) + return err; + if (b == 0) + return grub_error (GRUB_ERR_IO, "no SPD found"); + size = b; + + ((grub_uint8_t *) res)[0] = b; + for (ptr = 1; ptr < size; ptr++) + { + err = grub_cs5536_read_spd_byte (smbbase, dev, ptr, + &((grub_uint8_t *) res)[ptr]); + if (err) + return err; + } + return GRUB_ERR_NONE; +} diff --git a/commands/mips/yeeloong/lsspd.c b/commands/mips/yeeloong/lsspd.c new file mode 100644 index 000000000..539cda34c --- /dev/null +++ b/commands/mips/yeeloong/lsspd.c @@ -0,0 +1,92 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_lsspd (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_pci_device_t dev; + grub_port_t smbbase; + int i; + grub_err_t err; + + if (!grub_cs5536_find (&dev)) + { + grub_printf ("No CS5536 found\n"); + return GRUB_ERR_NONE; + } + grub_printf ("CS5536 at %d:%d.%d\n", grub_pci_get_bus (dev), + grub_pci_get_device (dev), grub_pci_get_function (dev)); + + err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase); + if (err) + return err; + + grub_printf ("SMB base = 0x%x\n", smbbase); + + for (i = GRUB_SMB_RAM_START_ADDR; + i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++) + { + struct grub_smbus_spd spd; + grub_memset (&spd, 0, sizeof (spd)); + grub_printf ("Device %d\n", i); + err = grub_cs5536_read_spd (smbbase, i, &spd); + if (err) + { + grub_print_error (); + continue; + } + grub_printf ("Written SPD bytes: %d B.\n", spd.written_size); + grub_printf ("Total flash size: %d B.\n", 1 << spd.log_total_flash_size); + if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2) + { + char str[sizeof (spd.ddr2.part_number) + 1]; + grub_printf ("Memory type: DDR2.\n"); + grub_memcpy (str, spd.ddr2.part_number, + sizeof (spd.ddr2.part_number)); + str[sizeof (spd.ddr2.part_number)] = 0; + grub_printf ("Part no: %s.\n", str); + } + else + grub_printf ("Memory type: Unknown.\n"); + } + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(lsspd) +{ + cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0, + "Print Memory information."); +} + +GRUB_MOD_FINI(lsspd) +{ + grub_unregister_command (cmd); +} diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index eb0dc9676..901a63dd0 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -73,6 +73,17 @@ datehook_mod_SOURCES = hook/datehook.c datehook_mod_CFLAGS = $(COMMON_CFLAGS) datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For lsspd.mod +pkglib_MODULES += lsspd.mod +lsspd_mod_SOURCES = commands/mips/yeeloong/lsspd.c +lsspd_mod_CFLAGS = $(COMMON_CFLAGS) +lsspd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cs5536.mod +pkglib_MODULES += cs5536.mod +cs5536_mod_SOURCES = bus/cs5536.c +cs5536_mod_CFLAGS = $(COMMON_CFLAGS) +cs5536_mod_LDFLAGS = $(COMMON_LDFLAGS) sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/disk/ata.c b/disk/ata.c index 687ed9378..662fe71a7 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -24,6 +24,7 @@ #include #include #include +#include /* At the moment, only two IDE ports are supported. */ static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; @@ -408,7 +409,7 @@ grub_ata_pciinit (grub_pci_device_t dev, class = grub_pci_read (addr); /* AMD CS5536 Southbridge. */ - if (pciid == 0x208f1022) + if (pciid == GRUB_CS5536_PCIID) { cs5536 = 1; nports = 1; diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h new file mode 100644 index 000000000..233362160 --- /dev/null +++ b/include/grub/cs5536.h @@ -0,0 +1,62 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_CS5536_HEADER +#define GRUB_CS5536_HEADER 1 + +#include +#include +#include + +#define GRUB_CS5536_PCIID 0x208f1022 +#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 +#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 +#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc +#define GRUB_CS5536_MSR_SMB_BAR 0x8000000b +#define GRUB_CS5536_SMB_REG_DATA 0x0 +#define GRUB_CS5536_SMB_REG_STATUS 0x1 +#define GRUB_CS5536_SMB_REG_CTRL1 0x3 +#define GRUB_CS5536_SMB_REG_CTRL1_START 0x01 +#define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02 +#define GRUB_CS5536_SMB_REG_CTRL1_ACK 0x10 +#define GRUB_CS5536_SMB_REG_ADDR 0x4 +#define GRUB_CS5536_SMB_REG_ADDR_MASTER 0x0 +#define GRUB_CS5536_SMB_REG_CTRL2 0x5 +#define GRUB_CS5536_SMB_REG_CTRL2_ENABLE 0x1 +#define GRUB_CS5536_SMB_REG_CTRL3 0x6 + +#define GRUB_CS5536_LBAR_ADDR_MASK 0x000000000000fff8ULL +#define GRUB_CS5536_LBAR_ADDR_OFF 3 +#define GRUB_CS5536_LBAR_ENABLE 0x0000000100000000ULL +#define GRUB_SMB_RAM_START_ADDR 0x50 +#define GRUB_SMB_RAM_NUM_MAX 0x08 + +int grub_cs5536_find (grub_pci_device_t *devp); + +grub_uint64_t grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr); +void grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr, + grub_uint64_t val); +grub_err_t grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res); +grub_err_t grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, + struct grub_smbus_spd *res); +grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase); +grub_err_t grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, + grub_port_t *smbbase); + +#endif diff --git a/include/grub/smbus.h b/include/grub/smbus.h new file mode 100644 index 000000000..6e9b5005c --- /dev/null +++ b/include/grub/smbus.h @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_SMBUS_HEADER +#define GRUB_SMBUS_HEADER 1 + +struct grub_smbus_spd +{ + grub_uint8_t written_size; + grub_uint8_t log_total_flash_size; +#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8 + grub_uint8_t memory_type; + union + { + grub_uint8_t unknown[253]; + struct { + grub_uint8_t unused1[70]; + grub_uint8_t part_number[18]; + grub_uint8_t unused2[165]; + } ddr2; + }; +}; + +#endif From 1eb746f2749f09ab7e1f8e83bc5cda7fb24bafbc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Feb 2010 22:40:53 +0100 Subject: [PATCH 028/503] Initialise remaining UART registers on Yeeloong --- include/grub/serial.h | 10 ++++++++-- term/serial.c | 11 +++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/grub/serial.h b/include/grub/serial.h index 1c35b4093..758b6fb3e 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -59,9 +59,15 @@ #define UART_DLAB 0x80 /* Enable the FIFO. */ -#define UART_ENABLE_FIFO 0xC7 +#define UART_ENABLE_FIFO_TRIGGER14 0xC7 + +/* Enable the FIFO. */ +#define UART_ENABLE_FIFO_TRIGGER1 0x07 /* Turn on DTR, RTS, and OUT2. */ -#define UART_ENABLE_MODEM 0x0B +#define UART_ENABLE_DTRRTS 0x03 + +/* Turn on DTR, RTS, and OUT2. */ +#define UART_ENABLE_OUT2 0x08 #endif /* ! GRUB_SERIAL_MACHINE_HEADER */ diff --git a/term/serial.c b/term/serial.c index 05497ce40..2dbebc2f1 100644 --- a/term/serial.c +++ b/term/serial.c @@ -300,10 +300,17 @@ serial_hw_init (void) /* In Yeeloong serial port has only 3 wires. */ #ifndef GRUB_MACHINE_MIPS_YEELOONG /* Enable the FIFO. */ - grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR); + grub_outb (UART_ENABLE_FIFO_TRIGGER1, serial_settings.port + UART_FCR); + + /* Turn on DTR and RTS. */ + grub_outb (UART_ENABLE_DTRRTS, serial_settings.port + UART_MCR); +#else + /* Enable the FIFO. */ + grub_outb (UART_ENABLE_FIFO_TRIGGER14, serial_settings.port + UART_FCR); /* Turn on DTR, RTS, and OUT2. */ - grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR); + grub_outb (UART_ENABLE_DTRRTS | UART_ENABLE_OUT2, + serial_settings.port + UART_MCR); #endif /* Drain the input buffer. */ From a1efcc79d346648871c976543d43ed1e9ad38f7a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Feb 2010 22:41:29 +0100 Subject: [PATCH 029/503] Firmware startup block (for now just output a string on console) --- include/grub/mips/yeeloong/serial.h | 5 ++ kern/mips/yeeloong/fwstart.S | 81 +++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 kern/mips/yeeloong/fwstart.S diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/yeeloong/serial.h index 9390ea18a..bced102b6 100644 --- a/include/grub/mips/yeeloong/serial.h +++ b/include/grub/mips/yeeloong/serial.h @@ -19,6 +19,11 @@ #ifndef GRUB_MACHINE_SERIAL_HEADER #define GRUB_MACHINE_SERIAL_HEADER 1 +#ifndef ASM_FILE #define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 } +#else +#define GRUB_MACHINE_SERIAL_PORT_HI 0xbff0 +#define GRUB_MACHINE_SERIAL_PORT_LO 0x03f8 +#endif #endif diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S new file mode 100644 index 000000000..5132d7584 --- /dev/null +++ b/kern/mips/yeeloong/fwstart.S @@ -0,0 +1,81 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + + .set noreorder + .set noat + .set nomacro + + bal serial_hw_init + nop +self: + b self + nop + + /* Same as similarly named C function but in asm since + we need it early. */ + /* In: none. Out: none. Clobbered: $t0, $t1, $a0. */ +serial_hw_init: + lui $t0, GRUB_MACHINE_SERIAL_PORT_HI + + /* Turn off the interrupt. */ + sb $zero, (GRUB_MACHINE_SERIAL_PORT_LO + UART_IER)($t0) + + /* Set DLAB. */ + ori $t1, $zero, UART_DLAB + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LCR)($t0) + + /* Set the baud rate 115200. */ + ori $t1, $zero, 2 + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_DLL)($t0) + sb $zero, (GRUB_MACHINE_SERIAL_PORT_LO + UART_DLH)($t0) + + /* Set the line status. */ + ori $t1, $zero, (UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT) + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LCR)($t0) + + /* Enable the FIFO. */ + ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1 + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_FCR)($t0) + + /* Turn on DTR and RTS. */ + ori $t1, $zero, UART_ENABLE_DTRRTS + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_MCR)($t0) + + lui $t0, 0xbff0 + addiu $t0, $t0, 0x03f8 + + /* Let message return to original caller. */ + lui $a0, %hi(notification_string) + addiu $a0, $a0, %lo(notification_string) + + /* Print message on serial console. */ + /* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */ +message: + lui $t0, GRUB_MACHINE_SERIAL_PORT_HI +1: + lb $t1, 0($a0) + addiu $a0, $a0, 1 + bne $t1, $zero, 1b + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0) + jr $ra + nop + +notification_string: .asciz "GRUB " From 7517048135ddc577be71751bca56dedfe37f00e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Feb 2010 21:10:58 +0100 Subject: [PATCH 030/503] Working SPD reading in fwstart.img --- bus/cs5536.c | 6 +- conf/mips-yeeloong.rmk | 8 + include/grub/cs5536.h | 21 ++- include/grub/mips/yeeloong/boot.h | 27 ++++ include/grub/mips/yeeloong/pci.h | 10 ++ include/grub/pci.h | 4 + include/grub/smbus.h | 3 + kern/mips/yeeloong/fwstart.S | 254 +++++++++++++++++++++++++++++- 8 files changed, 321 insertions(+), 12 deletions(-) diff --git a/bus/cs5536.c b/bus/cs5536.c index 3a7ac2bb1..f481397b7 100644 --- a/bus/cs5536.c +++ b/bus/cs5536.c @@ -80,11 +80,11 @@ grub_cs5536_smbus_wait (grub_port_t smbbase) { grub_uint8_t status; status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS); - if (status & (1 << 6)) + if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST) return GRUB_ERR_NONE; - if (status & (1 << 5)) + if (status & GRUB_CS5536_SMB_REG_STATUS_BER) return grub_error (GRUB_ERR_IO, "SM bus error"); - if (status & (1 << 4)) + if (status & GRUB_CS5536_SMB_REG_STATUS_NACK) return grub_error (GRUB_ERR_IO, "NACK received"); if (grub_get_time_ms () > start + 40) return grub_error (GRUB_ERR_IO, "SM stalled"); diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 901a63dd0..aa3e96fa0 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -30,6 +30,14 @@ kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_FORMAT = binary +pkglib_IMAGES += fwstart.img +fwstart_img_SOURCES = kern/$(target_cpu)/$(target_machine)/fwstart.S +fwstart_img_CFLAGS = $(COMMON_CFLAGS) +fwstart_img_ASFLAGS = $(COMMON_ASFLAGS) +fwstart_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ + -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic +fwstart_img_FORMAT = binary + # For ata.mod. pkglib_MODULES += ata.mod ata_mod_SOURCES = disk/ata.c diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index 233362160..51a21eb6e 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -19,17 +19,23 @@ #ifndef GRUB_CS5536_HEADER #define GRUB_CS5536_HEADER 1 +#ifndef ASM_FILE #include #include #include +#endif #define GRUB_CS5536_PCIID 0x208f1022 #define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 #define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 #define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc #define GRUB_CS5536_MSR_SMB_BAR 0x8000000b +#define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c #define GRUB_CS5536_SMB_REG_DATA 0x0 #define GRUB_CS5536_SMB_REG_STATUS 0x1 +#define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) +#define GRUB_CS5536_SMB_REG_STATUS_BER (1 << 5) +#define GRUB_CS5536_SMB_REG_STATUS_NACK (1 << 4) #define GRUB_CS5536_SMB_REG_CTRL1 0x3 #define GRUB_CS5536_SMB_REG_CTRL1_START 0x01 #define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02 @@ -41,11 +47,19 @@ #define GRUB_CS5536_SMB_REG_CTRL3 0x6 #define GRUB_CS5536_LBAR_ADDR_MASK 0x000000000000fff8ULL -#define GRUB_CS5536_LBAR_ADDR_OFF 3 #define GRUB_CS5536_LBAR_ENABLE 0x0000000100000000ULL -#define GRUB_SMB_RAM_START_ADDR 0x50 -#define GRUB_SMB_RAM_NUM_MAX 0x08 +/* PMON-compatible LBARs. */ +#define GRUB_CS5536_LBAR_GPIO 0x0b000 +#define GRUB_CS5536_LBAR_SMBUS 0x0b390 + +#define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) +#define GRUB_GPIO_REG_OUT_EN 0x4 +#define GRUB_GPIO_REG_OUT_AUX1 0x10 +#define GRUB_GPIO_REG_IN_EN 0x20 +#define GRUB_GPIO_REG_IN_AUX1 0x34 + +#ifndef ASM_FILE int grub_cs5536_find (grub_pci_device_t *devp); grub_uint64_t grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr); @@ -58,5 +72,6 @@ grub_err_t grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase); grub_err_t grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, grub_port_t *smbbase); +#endif #endif diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h index e69de29bb..205c557fe 100644 --- a/include/grub/mips/yeeloong/boot.h +++ b/include/grub/mips/yeeloong/boot.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +#define GRUB_MACHINE_FLASH_START 0xbfc00000 +#define GRUB_MACHINE_FLASH_TLB_REFILL 0xbfc00200 +#define GRUB_MACHINE_FLASH_CACHE_ERROR 0xbfc00300 +#define GRUB_MACHINE_FLASH_OTHER_EXCEPTION 0xbfc00380 + +#endif diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index c7bd31d4f..f50cdcb35 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -19,16 +19,24 @@ #ifndef GRUB_MACHINE_PCI_H #define GRUB_MACHINE_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 #define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 #define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 + +#ifndef ASM_FILE #define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) +#else +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_HI 0xbfe0 +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_LO 0x0118 +#endif #define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 #define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) @@ -46,6 +54,7 @@ #define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000 #define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 +#ifndef ASM_FILE static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { @@ -101,5 +110,6 @@ void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), volatile void *mem, grub_size_t size __attribute__ ((unused))); +#endif #endif /* GRUB_MACHINE_PCI_H */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 1f3ac7fc7..17f769f4c 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -19,8 +19,10 @@ #ifndef GRUB_PCI_H #define GRUB_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif #define GRUB_PCI_ADDR_SPACE_MASK 0x01 #define GRUB_PCI_ADDR_SPACE_MEMORY 0x00 @@ -66,6 +68,7 @@ #define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MAX_LAT 0x3f +#ifndef ASM_FILE typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_UTIL @@ -106,5 +109,6 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, int reg); void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); +#endif #endif /* GRUB_PCI_H */ diff --git a/include/grub/smbus.h b/include/grub/smbus.h index 6e9b5005c..b9cc6ab9e 100644 --- a/include/grub/smbus.h +++ b/include/grub/smbus.h @@ -19,6 +19,9 @@ #ifndef GRUB_SMBUS_HEADER #define GRUB_SMBUS_HEADER 1 +#define GRUB_SMB_RAM_START_ADDR 0x50 +#define GRUB_SMB_RAM_NUM_MAX 0x08 + struct grub_smbus_spd { grub_uint8_t written_size; diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index 5132d7584..59fe4d3e6 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -17,17 +17,107 @@ */ #include +#include +#include +#include #include +#include .set noreorder .set noat .set nomacro + .global start,_start,__start +start: +_start: +__start: bal serial_hw_init nop -self: - b self - nop + /* Find CS5536 controller. */ + /* $t4 chooses device in priority encoding. */ + /* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG. + This way we don't need to sacrifice a register for it. */ + /* We have only one bus (0). Function is 0. */ + lui $t0, GRUB_MACHINE_PCI_CONF_CTRL_REG_HI + lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE) + lui $t3, %hi(GRUB_CS5536_PCIID) + addiu $t3, $t3, %lo(GRUB_CS5536_PCIID) + ori $t4, $zero, 1 + lui $a0, %hi(no_cs5536) +1: + andi $t4, $t4, 0xffff + beql $t4, $zero, fatal + addiu $a0, $a0, %lo(no_cs5536) + sw $t4, GRUB_MACHINE_PCI_CONF_CTRL_REG_LO($t0) + lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1) + bnel $t2, $t3, 1b + sll $t4, $t4, 1 + + bal message + addiu $a0, $a0, %lo(cs5536_found) + bal printhex + move $a0, $t4 + + /* Initialise SMBus controller. */ + /* Set GPIO LBAR. */ + lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR) + addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR) + ori $a1, $zero, GRUB_CS5536_LBAR_GPIO + /* Set mask to 0xf and enabled bit to 1. */ + bal wrmsr + ori $a2, $zero, 0xf001 + + /* Set SMBUS LBAR. */ + lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR) + addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR) + ori $a1, $zero, GRUB_CS5536_LBAR_SMBUS + /* Set mask to 0xf and enabled bit to 1. */ + bal wrmsr + ori $a2, $zero, 0xf001 + + lui $a0, %hi(smbus_enabled) + bal message + addiu $a0, $a0, %lo(smbus_enabled) + + /* Enable SMBus controller pins. */ + lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO) + ori $t1, $zero, GRUB_GPIO_SMBUS_PINS + sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_EN) ($t0) + sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_AUX1) ($t0) + sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_EN) ($t0) + sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_AUX1) ($t0) + + lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS) + + /* Disable SMB. */ + sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) + + /* Disable interrupts. */ + sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1) ($t0) + + /* Set as master. */ + sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_ADDR) ($t0) + + /* Launch SMBus controller at slowest speed possible. */ + ori $t1, $zero, 0xff + sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0) + sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) + + ori $a0, $zero, 0x50 + bal read_spd + move $a1, $zero + bal printhex + move $a0, $v0 + + ori $a0, $zero, 0x50 + bal read_spd + ori $a1, $zero, 2 + bal printhex + move $a0, $v0 + + lui $a0, %hi(not_implemented) + b fatal + addiu $a0, $a0, %lo(not_implemented) /* Same as similarly named C function but in asm since we need it early. */ @@ -70,12 +160,164 @@ serial_hw_init: /* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */ message: lui $t0, GRUB_MACHINE_SERIAL_PORT_HI -1: +1: + lb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LSR)($t0) + andi $t1, $t1, UART_EMPTY_TRANSMITTER + beq $t1, $zero, 1b + nop lb $t1, 0($a0) - addiu $a0, $a0, 1 + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0) bne $t1, $zero, 1b - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0) + addiu $a0, $a0, 1 jr $ra nop + /* Print 32-bit hexadecimal on serial. + In: $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2 + */ +printhex: + lui $t0, GRUB_MACHINE_SERIAL_PORT_HI + ori $t2, $zero, 8 +1: + lb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LSR)($t0) + andi $t1, $t1, UART_EMPTY_TRANSMITTER + beq $t1, $zero, 1b + nop + srl $t1, $a0, 28 + addiu $t1, $t1, -10 + blt $t1, $zero, 2f + sll $a0, $a0, 4 + addiu $t1, $t1, 'A'-10-'0' +2: addiu $t1, $t1, '0'+10 + sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0) + addiu $t2, $t2, -1 + bne $t2, $zero, 1b + nop + jr $ra + nop + +fatal: + bal message + nop +self: + b self + nop + + . = start + GRUB_MACHINE_FLASH_TLB_REFILL - GRUB_MACHINE_FLASH_START +tlb_refill: + lui $a0, %hi(unhandled_tlb_refill) + b fatal + addiu $a0, $a0, %lo(unhandled_tlb_refill) + + . = start + GRUB_MACHINE_FLASH_CACHE_ERROR - GRUB_MACHINE_FLASH_START +cache_error: + lui $a0, %hi(unhandled_cache_error) + b fatal + addiu $a0, $a0, %lo(unhandled_cache_error) + + . = start + GRUB_MACHINE_FLASH_OTHER_EXCEPTION - GRUB_MACHINE_FLASH_START +other_exception: + lui $a0, %hi(unhandled_exception) + b fatal + addiu $a0, $a0, %lo(unhandled_exception) + + /* Write CS5536 MSR. + In: $a0 address, $a1 lower word, $a2 upper word. + Out: None + Clobbered: $t0 + */ +wrmsr: + lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE) + sw $a0, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_ADDR) ($t0) + sw $a1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA0) ($t0) + jr $ra + sw $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA1) ($t0) + + /* Wait for SMBus data or empty transmitter. */ + /* In: $a0 = exception handler. Out: none. Clobbered: $t0, $t1 */ +smbus_wait: +1: + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE) + lb $t0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE) ($t0) + andi $t1, $t0, GRUB_CS5536_SMB_REG_STATUS_SDAST + bne $t1, $zero, return + nop + andi $t1, $t0, (GRUB_CS5536_SMB_REG_STATUS_BER | GRUB_CS5536_SMB_REG_STATUS_NACK) + beq $t1, $zero, 1b + nop + jr $a0 + nop +return: + jr $ra + nop + + /* Read SPD byte. In: $a0 device, $a1 byte. Out: $v0 read byte (0x100 on failure). + Clobbered: $t0, $t1, $t2, $t3, $a0. */ +read_spd: + move $t2, $a0 + move $t3, $ra + lui $a0, %hi(read_spd_fail) + addiu $a0, $a0, %hi(read_spd_fail) + + /* Send START. */ + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START + bal smbus_wait + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + + /* Send device address. */ + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) + sll $t1, $t2, 1 + bal smbus_wait + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) + + /* Send ACK. */ + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_ACK + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + + /* Send byte address. */ + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) + bal smbus_wait + sb $a1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) + + /* Send START. */ + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START + bal smbus_wait + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + + /* Send device address. */ + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) + sll $t1, $t2, 1 + ori $t1, $t1, 1 + bal smbus_wait + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) + + /* Send STOP. */ + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) + lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_STOP + bal smbus_wait + sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0) + + lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) + lb $v0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) + jr $t3 + andi $v0, $v0, 0xff +read_spd_fail: + jr $t3 + ori $v0, $v0, 0x100 + notification_string: .asciz "GRUB " +no_cs5536: .asciz "No CS5536 found.\n\r" +cs5536_found: .asciz "CS5536 at " +sm_failed: .asciz "SM transaction failed.\n\r" +not_implemented: .asciz "Nothing more is implemented. Bye.\n\r" +unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r" +unhandled_cache_error: .asciz "Unhandled cache error.\n\r" +unhandled_exception: .asciz "Unhandled exception.\n\r" +smbus_enabled: .asciz "SMBus controller enabled.\n\r" From 813a5f2d33cd81da080daba410543f68aa7382e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Mar 2010 18:53:34 +0100 Subject: [PATCH 031/503] Init DDR2 controller --- include/grub/mips/yeeloong/boot.h | 3 + include/grub/smbus.h | 34 +++- kern/mips/yeeloong/fwstart.S | 279 ++++++++++++++++++++++++++---- util/grub-mkrawimage.c | 26 ++- 4 files changed, 307 insertions(+), 35 deletions(-) diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h index 205c557fe..6a4189ede 100644 --- a/include/grub/mips/yeeloong/boot.h +++ b/include/grub/mips/yeeloong/boot.h @@ -24,4 +24,7 @@ #define GRUB_MACHINE_FLASH_CACHE_ERROR 0xbfc00300 #define GRUB_MACHINE_FLASH_OTHER_EXCEPTION 0xbfc00380 +#define GRUB_MACHINE_DDR2_BASE 0xaffffe00 +#define GRUB_MACHINE_DDR2_REG1_HI_8BANKS 0x00000001 + #endif diff --git a/include/grub/smbus.h b/include/grub/smbus.h index b9cc6ab9e..0b8e6718f 100644 --- a/include/grub/smbus.h +++ b/include/grub/smbus.h @@ -22,21 +22,49 @@ #define GRUB_SMB_RAM_START_ADDR 0x50 #define GRUB_SMB_RAM_NUM_MAX 0x08 +#define GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR 2 +#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8 +#define GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR 17 +#define GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR 3 +#define GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR 4 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_ADDR 5 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK 0x7 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR 18 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE 5 +#define GRUB_SMBUS_SPD_MEMORY_TRAS_ADDR 30 +#define GRUB_SMBUS_SPD_MEMORY_TRTP_ADDR 38 + +#ifndef ASM_FILE + struct grub_smbus_spd { grub_uint8_t written_size; grub_uint8_t log_total_flash_size; -#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8 grub_uint8_t memory_type; union { grub_uint8_t unknown[253]; struct { - grub_uint8_t unused1[70]; + grub_uint8_t num_rows; + grub_uint8_t num_columns; + grub_uint8_t num_of_ranks; + grub_uint8_t unused1[12]; + grub_uint8_t num_of_banks; + grub_uint8_t unused2[2]; + grub_uint8_t cas_latency; + grub_uint8_t unused3[9]; + grub_uint8_t rank_capacity; + grub_uint8_t unused4[1]; + grub_uint8_t tras; + grub_uint8_t unused5[7]; + grub_uint8_t trtp; + grub_uint8_t unused6[31]; grub_uint8_t part_number[18]; - grub_uint8_t unused2[165]; + grub_uint8_t unused7[165]; } ddr2; }; }; #endif + +#endif diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index 59fe4d3e6..3dccb65fd 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -22,6 +22,7 @@ #include #include #include +#include .set noreorder .set noat @@ -103,21 +104,102 @@ __start: sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0) sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) - ori $a0, $zero, 0x50 + /* Yeeloong has only one memory slot. */ + /* Output first byte on serial for debugging. */ + ori $a1, $zero, GRUB_SMB_RAM_START_ADDR bal read_spd - move $a1, $zero + move $a0, $zero bal printhex move $a0, $v0 - ori $a0, $zero, 0x50 bal read_spd - ori $a1, $zero, 2 + ori $a0, $zero, 2 + ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 + lui $a0, %hi(unimplemented_memory_type) + bne $t0, $v0, fatal + addiu $a0, $a0, %hi(unimplemented_memory_type) + + /* And here is our goal: DDR2 controller initialisation. */ + lui $t0, 0xbfe0 + ld $t1, 0x0180($t0) + andi $t1, $t1, 0x4ff + sd $t1, 0x0180($t0) + + b continue + + . = start + GRUB_MACHINE_FLASH_TLB_REFILL - GRUB_MACHINE_FLASH_START +tlb_refill: + mfc0 $s1, $14 + mfc0 $s2, $8 + move $s3, $ra + lui $a0, %hi(epc) + bal message + addiu $a0, $a0, %lo(epc) + bal printhex - move $a0, $v0 + move $a0, $s1 + + lui $a0, %hi(badvaddr) + bal message + addiu $a0, $a0, %lo(badvaddr) + + bal printhex + move $a0, $s2 + + lui $a0, %hi(return_msg) + bal message + addiu $a0, $a0, %lo(return_msg) + + bal printhex + move $a0, $s3 - lui $a0, %hi(not_implemented) + lui $a0, %hi(newline) + bal message + addiu $a0, $a0, %lo(newline) + + lui $a0, %hi(unhandled_tlb_refill) b fatal - addiu $a0, $a0, %lo(not_implemented) + addiu $a0, $a0, %lo(unhandled_tlb_refill) + + . = start + GRUB_MACHINE_FLASH_CACHE_ERROR - GRUB_MACHINE_FLASH_START +cache_error: + lui $a0, %hi(unhandled_cache_error) + b fatal + addiu $a0, $a0, %lo(unhandled_cache_error) + + . = start + GRUB_MACHINE_FLASH_OTHER_EXCEPTION - GRUB_MACHINE_FLASH_START +other_exception: + mfc0 $s0, $13 + mfc0 $s1, $14 + mfc0 $s2, $8 + lui $a0, %hi(cause) + bal message + addiu $a0, $a0, %lo(cause) + + bal printhex + move $a0, $s0 + + lui $a0, %hi(epc) + bal message + addiu $a0, $a0, %lo(epc) + + bal printhex + move $a0, $s1 + + lui $a0, %hi(badvaddr) + bal message + addiu $a0, $a0, %lo(badvaddr) + + bal printhex + move $a0, $s2 + + lui $a0, %hi(newline) + bal message + addiu $a0, $a0, %lo(newline) + + lui $a0, %hi(unhandled_exception) + b fatal + addiu $a0, $a0, %lo(unhandled_exception) /* Same as similarly named C function but in asm since we need it early. */ @@ -171,7 +253,7 @@ message: addiu $a0, $a0, 1 jr $ra nop - + /* Print 32-bit hexadecimal on serial. In: $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2 */ @@ -202,25 +284,7 @@ fatal: self: b self nop - - . = start + GRUB_MACHINE_FLASH_TLB_REFILL - GRUB_MACHINE_FLASH_START -tlb_refill: - lui $a0, %hi(unhandled_tlb_refill) - b fatal - addiu $a0, $a0, %lo(unhandled_tlb_refill) - - . = start + GRUB_MACHINE_FLASH_CACHE_ERROR - GRUB_MACHINE_FLASH_START -cache_error: - lui $a0, %hi(unhandled_cache_error) - b fatal - addiu $a0, $a0, %lo(unhandled_cache_error) - - . = start + GRUB_MACHINE_FLASH_OTHER_EXCEPTION - GRUB_MACHINE_FLASH_START -other_exception: - lui $a0, %hi(unhandled_exception) - b fatal - addiu $a0, $a0, %lo(unhandled_exception) - + /* Write CS5536 MSR. In: $a0 address, $a1 lower word, $a2 upper word. Out: None @@ -251,7 +315,7 @@ return: jr $ra nop - /* Read SPD byte. In: $a0 device, $a1 byte. Out: $v0 read byte (0x100 on failure). + /* Read SPD byte. In: $a0 byte, $a1 device. Out: $v0 read byte (0x100 on failure). Clobbered: $t0, $t1, $t2, $t3, $a0. */ read_spd: move $t2, $a0 @@ -268,7 +332,7 @@ read_spd: /* Send device address. */ lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) - sll $t1, $t2, 1 + sll $t1, $a1, 1 bal smbus_wait sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) @@ -281,7 +345,7 @@ read_spd: /* Send byte address. */ lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) bal smbus_wait - sb $a1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) + sb $t2, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) /* Send START. */ lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) @@ -292,7 +356,7 @@ read_spd: /* Send device address. */ lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) - sll $t1, $t2, 1 + sll $t1, $a1, 1 ori $t1, $t1, 1 bal smbus_wait sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0) @@ -321,3 +385,156 @@ unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r" unhandled_cache_error: .asciz "Unhandled cache error.\n\r" unhandled_exception: .asciz "Unhandled exception.\n\r" smbus_enabled: .asciz "SMBus controller enabled.\n\r" +unimplemented_memory_type: .asciz "non-DDR2 memory isn't supported.\n\r" +no_cas_latency: .asciz "Couldn't determine CAS latency.\n\r" +cause: .asciz "Cause: " +epc: .asciz "\n\rEPC: " +badvaddr: .asciz "\n\rBadVaddr: " +newline: .asciz "\n\r" +return_msg: .asciz "\n\rReturn address: " + + .p2align 3 + +regdump: + .quad 0x0100010000000101 /* 0 */ + .quad 0x0100010100000000 /* 2 */ + .quad 0x0101000001000000 /* 3 */ + .quad 0x0100020200010101 /* 4 */ + .quad 0x0a04030603050203 /* 6 */ + .quad 0x0f0e040000010a0b /* 7 */ + .quad 0x0000010200000102 /* 8 */ + .quad 0x0000060c00000000 /* 9 */ + .quad 0x2323233f3f1f0200 /* a */ + .quad 0x5f7f232323232323 /* b */ + .quad 0x002a3c0615000000 /* c */ + .quad 0x002a002a002a002a /* d */ + .quad 0x002a002a002a002a /* e */ + .quad 0x00b40020006d0004 /* f */ + .quad 0x070007ff00000087 /* 10 */ + .quad 0x000000000016101f /* 11 */ + .quad 0x001c000000000000 /* 12 */ + .quad 0x28e1000200c8006b /* 13 */ + .quad 0x0000204200c8002f /* 14 */ + .quad 0x0000000000030d40 /* 15 */ + .quad 0 /* 16 */ + .quad 0 /* 17 */ + .quad 0 /* 18 */ + .quad 0 /* 19 */ + .quad 0 /* 1a */ + .quad 0 /* 1b */ + .quad 0 /* 1c */ + + .p2align + +write_dumpreg: + ld $t2, 0($t6) + sd $t2, 0($t4) + addiu $t4, $t4, 0x10 + jr $ra + addiu $t6, $t6, 0x8 + +continue: + lui $t4, %hi(GRUB_MACHINE_DDR2_BASE) + addiu $t4, $t4, %lo(GRUB_MACHINE_DDR2_BASE) + lui $t6, %hi(regdump) + + /* 0 */ + bal write_dumpreg + addiu $t6, $t6, %lo(regdump) + + /* 1 */ + ori $a1, $a1, 0x50 + move $t8, $zero + lui $t5, 0x0001 + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR + ori $t7, $zero, 8 + bne $v0, $t7, 1f + ori $t5, $t5, 0x0001 + ori $t8, $t8, GRUB_MACHINE_DDR2_REG1_HI_8BANKS +1: + dsll $t8, $t8, 32 + or $t5, $t5, $t8 + sd $t5, 0 ($t4) + addiu $t4, $t4, 0x10 + + /* 2 */ + bal write_dumpreg + nop + + /* 3 */ + bal write_dumpreg + nop + + /* 4 */ + bal write_dumpreg + nop + + /* 5 */ + /* FIXME: figure termination resistance. */ + ori $t5, $zero, 0x2 + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR + /* $v0 = 15 - $v0. */ + xori $v0, $v0, 0xf + andi $v0, $v0, 0x7 + sll $v0, $v0, 8 + or $t5, $t5, $v0 + + /* Find the fastest supported CAS latency. */ + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR + ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE + ori $t1, $zero, (1 << GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE) +2: + and $t2, $t1, $v0 + bne $t2, $zero, 1f + ori $t3, $zero, 8 + lui $a0, %hi(no_cas_latency) + beq $t0, $t3, fatal + addiu $a0, $a0, %lo(no_cas_latency) + addiu $t0, $t0, 1 + b 2b + sll $t1, $t1, 1 +1: + sll $t0, $t0, 16 + or $t5, $t5, $t0 + + bal read_spd + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR + /* $v0 = 15 - ($v0 + 1) = 14 - $v0. */ + addiu $v0, $v0, 1 + xori $v0, $v0, 0xf + andi $v0, $v0, 0x7 + sll $v0, 24 + or $t5, $t5, $v0 + sd $t5, 0 ($t4) + + addiu $t4, $t4, 0x10 + + ori $t7, $zero, 0x16 + +1: + ld $t2, 0($t6) + sd $t2, 0($t4) + addiu $t4, $t4, 0x10 + addiu $t7, $t7, -1 + bne $t7, $zero, 1b + addiu $t6, $t6, 0x8 + + lui $t4, %hi(GRUB_MACHINE_DDR2_BASE) + ld $t5, (%lo(GRUB_MACHINE_DDR2_BASE) + 0x30) ($t4) + ori $t0, $zero, 1 + dsll $t0, $t0, 40 + or $t5, $t5, $t0 + sd $t5, (%lo(GRUB_MACHINE_DDR2_BASE) + 0x30) ($t4) + + /* Desactivate DDR2 registers. */ + lui $t0, 0xbfe0 + ld $t1, 0x0180($t0) + ori $t1, $t1, 0x100 + sd $t1, 0x0180($t0) + + addiu $a0, $zero, -1 + addiu $a1, $zero, -1 + addiu $a2, $zero, -1 diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 83bb51c02..2f721f6ed 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -391,7 +391,31 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (core_img); core_img = elf_img; core_size = program_size + sizeof (*ehdr) + sizeof (*phdr); - } + } + else + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + + boot_path = grub_util_get_path (dir, "fwstart.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); + + rom_size = core_size + boot_size; + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + memcpy (rom_img, boot_img, boot_size); + + memcpy (rom_img + boot_size, core_img, core_size); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + } #endif grub_util_write_image (core_img, core_size, out); From 5dd8753cc0351adbeb5eb271e2a34d2d0ba73329 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Mar 2010 18:57:31 +0100 Subject: [PATCH 032/503] Properly init even without pmon parameters --- kern/mips/startup.S | 9 ++++++- kern/mips/yeeloong/init.c | 56 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 5e3fb7ad5..e3ba131aa 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -48,8 +48,15 @@ codestart: /* Parse arguments. Has to be done before relocation. So need to do it in asm. */ #ifdef GRUB_MACHINE_MIPS_YEELOONG + move $s2, $zero + move $s3, $zero + move $s4, $zero + move $s5, $zero + /* $a2 has the environment. */ - move $t0, $a2 + addiu $t0, $a2, 1 + beq $t0, $zero, argdone + move $t0, $a2 argcont: lw $t1, 0($t0) beq $t1, $zero, argdone diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 14e8a39a2..f35605f63 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -27,6 +27,7 @@ #include #include #include +#include extern void grub_video_sm712_init (void); extern void grub_video_video_init (void); @@ -89,16 +90,67 @@ void grub_machine_init (void) { void *modend; + + /* FIXME: measure this. */ + if (grub_arch_busclock == 0) + { + grub_arch_busclock = 66000000; + grub_arch_cpuclock = 797000000; + } + + grub_install_get_time_ms (grub_rtc_get_time_ms); + + if (grub_arch_memsize == 0) + { + grub_port_t smbbase; + grub_err_t err; + grub_pci_device_t dev; + struct grub_smbus_spd spd; + unsigned totalmem; + int i; + + if (!grub_cs5536_find (&dev)) + grub_fatal ("No CS5536 found\n"); + + err = grub_cs5536_init_smbus (dev, 0x7ff, &smbbase); + if (err) + grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg); + + /* Yeeloong has only one memory slot. */ + err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd); + if (err) + grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg); + for (i = 5; i < 13; i++) + if (spd.ddr2.rank_capacity & (1 << (i & 7))) + break; + /* Something is wrong. */ + if (i == 13) + totalmem = 256; + else + totalmem = ((spd.ddr2.num_of_ranks + & GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK) + 1) << (i + 2); + + if (totalmem >= 256) + { + grub_arch_memsize = 256; + grub_arch_highmemsize = totalmem - 256; + } + else + { + grub_arch_memsize = (totalmem >> 20); + grub_arch_highmemsize = 0; + } + } + modend = get_modules_end (); grub_mm_init_region (modend, (grub_arch_memsize << 20) - (((grub_addr_t) modend) - GRUB_ARCH_LOWMEMVSTART)); /* FIXME: use upper memory as well. */ - grub_install_get_time_ms (grub_rtc_get_time_ms); /* Initialize output terminal (can't be done earlier, as gfxterm relies on a working heap. */ - grub_video_sm712_init (); grub_video_video_init (); + grub_video_sm712_init (); grub_video_bitmap_init (); grub_font_manager_init (); grub_term_gfxterm_init (); From 32f86589a6c13fe3e90d100bf7625970f1e1dfb8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Mar 2010 22:09:06 +0100 Subject: [PATCH 033/503] Video support in firmware --- video/sm712.c | 70 +++++- video/sm712_init.c | 546 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 607 insertions(+), 9 deletions(-) create mode 100644 video/sm712_init.c diff --git a/video/sm712.c b/video/sm712.c index a86470b7d..f0d0f29c4 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -27,6 +27,10 @@ #include #include +#include "sm712_init.c" + +#define GRUB_SM712_TOTAL_MEMORY_SPACE 0x700400 + static struct { struct grub_video_mode_info mode_info; @@ -55,7 +59,7 @@ grub_video_sm712_video_fini (void) { if (framebuffer.mapped) grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, - 1024 * 600 * 2); + GRUB_SM712_TOTAL_MEMORY_SPACE); return grub_video_fb_fini (); } @@ -67,6 +71,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, int depth; grub_err_t err; int found = 0; + unsigned i; auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) @@ -102,11 +107,6 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); - if (found && framebuffer.base == 0) - { - /* FIXME: change framebuffer base */ - } - /* Fill mode info details. */ framebuffer.mode_info.width = 1024; framebuffer.mode_info.height = 600; @@ -124,12 +124,64 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, framebuffer.mode_info.reserved_mask_size = 0; framebuffer.mode_info.reserved_field_pos = 0; framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); + + if (found && framebuffer.base == 0) + { + grub_pci_address_t addr; + /* FIXME: choose address dynamically if needed. */ + framebuffer.base = 0x04000000; + + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, framebuffer.base); + + /* Set latency. */ + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_CACHELINE); + grub_pci_write (addr, 0x8); + + /* Enable address spaces. */ + addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); + grub_pci_write (addr, 0x7); + } + /* We can safely discard volatile attribute. */ - framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, - framebuffer.base, - 1024 * 600 * 2); + framebuffer.ptr + = (void *) grub_pci_device_map_range (framebuffer.dev, + framebuffer.base, + GRUB_SM712_TOTAL_MEMORY_SPACE); framebuffer.mapped = 1; + /* Initialise SM712. */ + grub_outb (0x18, GRUB_MACHINE_PCI_IO_BASE + 0x3c4); + grub_outb (0x11, GRUB_MACHINE_PCI_IO_BASE + 0x3c5); + + /* Prevent garbage from appearing on the screen. */ + grub_memset (framebuffer.ptr, 0, + framebuffer.mode_info.height * framebuffer.mode_info.pitch); + + for (i = 0; i < ARRAY_SIZE (sm712_init); i++) + switch (sm712_init[i].directive) + { + case 1: + *(volatile grub_uint8_t *) ((char *) framebuffer.ptr + + sm712_init[i].addr) = sm712_init[i].val; + break; + case -1: + { + grub_uint8_t val = *(volatile grub_uint8_t *) + ((char *) framebuffer.ptr + sm712_init[i].addr); + (void) val; + } + break; + case 2: + *(volatile grub_uint16_t *) ((char *) framebuffer.ptr + + sm712_init[i].addr) = sm712_init[i].val; + break; + case 4: + *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + + sm712_init[i].addr) = sm712_init[i].val; + break; + } + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) diff --git a/video/sm712_init.c b/video/sm712_init.c new file mode 100644 index 000000000..02c64c453 --- /dev/null +++ b/video/sm712_init.c @@ -0,0 +1,546 @@ +/* Following sequence is a capture of sm712 initialisation sequence. */ +static struct +{ + int directive; + grub_uint32_t addr; + grub_uint32_t val; +} sm712_init[] = +{ + {1, 0x7003c4, 0x21}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x62}, + {1, 0x7003c5, 0x7a}, + {1, 0x7003c4, 0x6a}, + {1, 0x7003c5, 0x16}, + {1, 0x7003c4, 0x6b}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c6, 0x0}, + {1, 0x7003c4, 0x0}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c2, 0xeb}, + {1, 0x7003c4, 0x0}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x1}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x2}, + {1, 0x7003c5, 0xf}, + {1, 0x7003c4, 0x3}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4}, + {1, 0x7003c5, 0xe}, + {1, 0x7003c4, 0x10}, + {1, 0x7003c5, 0xc8}, + {1, 0x7003c4, 0x11}, + {1, 0x7003c5, 0x40}, + {1, 0x7003c4, 0x12}, + {1, 0x7003c5, 0x14}, + {1, 0x7003c4, 0x13}, + {1, 0x7003c5, 0x60}, + {1, 0x7003c4, 0x14}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x15}, + {1, 0x7003c5, 0xa}, + {1, 0x7003c4, 0x16}, + {1, 0x7003c5, 0x92}, + {1, 0x7003c4, 0x17}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x18}, + {1, 0x7003c5, 0x51}, + {1, 0x7003c4, 0x19}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1a}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x1b}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1e}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x1f}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x20}, + {1, 0x7003c5, 0xc4}, + {1, 0x7003c4, 0x21}, + {1, 0x7003c5, 0x30}, + {1, 0x7003c4, 0x22}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x23}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x24}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x30}, + {1, 0x7003c5, 0x28}, + {1, 0x7003c4, 0x31}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x32}, + {1, 0x7003c5, 0x24}, + {1, 0x7003c4, 0x33}, + {1, 0x7003c5, 0x9}, + {1, 0x7003c4, 0x34}, + {1, 0x7003c5, 0xc0}, + {1, 0x7003c4, 0x35}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x36}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x37}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x38}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x39}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x3a}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x3b}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x3c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x3d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x3e}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x3f}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x40}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x41}, + {1, 0x7003c5, 0xfc}, + {1, 0x7003c4, 0x42}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x43}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x44}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x45}, + {1, 0x7003c5, 0x18}, + {1, 0x7003c4, 0x46}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x47}, + {1, 0x7003c5, 0xfc}, + {1, 0x7003c4, 0x48}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x49}, + {1, 0x7003c5, 0xc}, + {1, 0x7003c4, 0x4a}, + {1, 0x7003c5, 0x44}, + {1, 0x7003c4, 0x4b}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x4c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4e}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x4f}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x50}, + {1, 0x7003c5, 0x6}, + {1, 0x7003c4, 0x51}, + {1, 0x7003c5, 0x68}, + {1, 0x7003c4, 0x52}, + {1, 0x7003c5, 0xa7}, + {1, 0x7003c4, 0x53}, + {1, 0x7003c5, 0x7f}, + {1, 0x7003c4, 0x54}, + {1, 0x7003c5, 0x83}, + {1, 0x7003c4, 0x55}, + {1, 0x7003c5, 0x24}, + {1, 0x7003c4, 0x56}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x57}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x58}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x59}, + {1, 0x7003c5, 0x60}, + {1, 0x7003c4, 0x5a}, + {1, 0x7003c5, 0x59}, + {1, 0x7003c4, 0x5b}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x5c}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x5d}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x5e}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x5f}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x60}, + {1, 0x7003c5, 0x1}, + {1, 0x7003c4, 0x61}, + {1, 0x7003c5, 0x80}, + {1, 0x7003c4, 0x63}, + {1, 0x7003c5, 0x1a}, + {1, 0x7003c4, 0x64}, + {1, 0x7003c5, 0x1a}, + {1, 0x7003c4, 0x65}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x66}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x67}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x68}, + {1, 0x7003c5, 0x50}, + {1, 0x7003c4, 0x69}, + {1, 0x7003c5, 0x3}, + {1, 0x7003c4, 0x6c}, + {1, 0x7003c5, 0x52}, + {1, 0x7003c4, 0x6d}, + {1, 0x7003c5, 0x89}, + {1, 0x7003c4, 0x6e}, + {1, 0x7003c5, 0x9}, + {1, 0x7003c4, 0x6f}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x70}, + {1, 0x7003c5, 0x4}, + {1, 0x7003c4, 0x71}, + {1, 0x7003c5, 0x45}, + {1, 0x7003c4, 0x72}, + {1, 0x7003c5, 0x30}, + {1, 0x7003c4, 0x73}, + {1, 0x7003c5, 0x30}, + {1, 0x7003c4, 0x74}, + {1, 0x7003c5, 0x40}, + {1, 0x7003c4, 0x75}, + {1, 0x7003c5, 0x20}, + {1, 0x7003c4, 0x80}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x81}, + {1, 0x7003c5, 0x7}, + {1, 0x7003c4, 0x82}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x83}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x84}, + {1, 0x7003c5, 0x8}, + {1, 0x7003c4, 0x85}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x86}, + {1, 0x7003c5, 0x42}, + {1, 0x7003c4, 0x87}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x88}, + {1, 0x7003c5, 0x59}, + {1, 0x7003c4, 0x89}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x8a}, + {1, 0x7003c5, 0x44}, + {1, 0x7003c4, 0x8b}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0x8c}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x8d}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0x8e}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x8f}, + {1, 0x7003c5, 0x3a}, + {1, 0x7003c4, 0x90}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x91}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x92}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0x93}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0xa0}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0xa1}, + {1, 0x7003c5, 0x10}, + {1, 0x7003c4, 0xa2}, + {1, 0x7003c5, 0x8}, + {1, 0x7003c4, 0xa3}, + {1, 0x7003c5, 0x0}, + {1, 0x7003c4, 0xa4}, + {1, 0x7003c5, 0x2}, + {1, 0x7003c4, 0xa5}, + {1, 0x7003c5, 0xed}, + {1, 0x7003c4, 0xa6}, + {1, 0x7003c5, 0xed}, + {1, 0x7003c4, 0xa7}, + {1, 0x7003c5, 0xed}, + {1, 0x7003c4, 0xa8}, + {1, 0x7003c5, 0x7b}, + {1, 0x7003c4, 0xa9}, + {1, 0x7003c5, 0xfb}, + {1, 0x7003c4, 0xaa}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0xab}, + {1, 0x7003c5, 0xff}, + {1, 0x7003c4, 0xac}, + {1, 0x7003c5, 0x97}, + {1, 0x7003c4, 0xad}, + {1, 0x7003c5, 0xef}, + {1, 0x7003c4, 0xae}, + {1, 0x7003c5, 0xbf}, + {1, 0x7003c4, 0xaf}, + {1, 0x7003c5, 0xdf}, + {1, 0x7003ce, 0x0}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x1}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x2}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x3}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x4}, + {1, 0x7003cf, 0x0}, + {1, 0x7003ce, 0x5}, + {1, 0x7003cf, 0x40}, + {1, 0x7003ce, 0x6}, + {1, 0x7003cf, 0x5}, + {1, 0x7003ce, 0x7}, + {1, 0x7003cf, 0xf}, + {1, 0x7003ce, 0x8}, + {1, 0x7003cf, 0xff}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003c1, 0x3e}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x1}, + {-1, 0x7003c1, 0x3b}, + {1, 0x7003c0, 0x1}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x2}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x2}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x3}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x3}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x4}, + {-1, 0x7003c1, 0x3b}, + {1, 0x7003c0, 0x4}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x5}, + {-1, 0x7003c1, 0x2f}, + {1, 0x7003c0, 0x5}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x6}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x6}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x7}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x7}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x8}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0x8}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x9}, + {-1, 0x7003c1, 0x3d}, + {1, 0x7003c0, 0x9}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xa}, + {-1, 0x7003c1, 0x1f}, + {1, 0x7003c0, 0xa}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xb}, + {-1, 0x7003c1, 0x1f}, + {1, 0x7003c0, 0xb}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xc}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0xc}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xd}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0xd}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xe}, + {-1, 0x7003c1, 0x3f}, + {1, 0x7003c0, 0xe}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0xf}, + {-1, 0x7003c1, 0x2e}, + {1, 0x7003c0, 0xf}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x10}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x41}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x11}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x12}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0xf}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x13}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x0}, + {-1, 0x7003da, 0x5}, + {1, 0x7003c0, 0x14}, + {-1, 0x7003c1, 0x0}, + {1, 0x7003c0, 0x0}, + {1, 0x7003d4, 0x0}, + {1, 0x7003d5, 0xa3}, + {1, 0x7003d4, 0x1}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x2}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x3}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x4}, + {1, 0x7003d5, 0x85}, + {1, 0x7003d4, 0x5}, + {1, 0x7003d5, 0x16}, + {1, 0x7003d4, 0x6}, + {1, 0x7003d5, 0x24}, + {1, 0x7003d4, 0x7}, + {1, 0x7003d5, 0xf5}, + {1, 0x7003d4, 0x8}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9}, + {1, 0x7003d5, 0x60}, + {1, 0x7003d4, 0xa}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xb}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xc}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xd}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xe}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xf}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x10}, + {1, 0x7003d5, 0x3}, + {1, 0x7003d4, 0x11}, + {1, 0x7003d5, 0x9}, + {1, 0x7003d4, 0x12}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x13}, + {1, 0x7003d5, 0x80}, + {1, 0x7003d4, 0x14}, + {1, 0x7003d5, 0x40}, + {1, 0x7003d4, 0x15}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x16}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x17}, + {1, 0x7003d5, 0xe3}, + {1, 0x7003d4, 0x18}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x30}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x31}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x32}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x33}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x34}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x35}, + {1, 0x7003d5, 0x80}, + {1, 0x7003d4, 0x36}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0x37}, + {1, 0x7003d5, 0x20}, + {1, 0x7003d4, 0x38}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x39}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x3a}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x3b}, + {1, 0x7003d5, 0x40}, + {1, 0x7003d4, 0x3c}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x3d}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x3e}, + {1, 0x7003d5, 0x46}, + {1, 0x7003d4, 0x3f}, + {1, 0x7003d5, 0x91}, + {1, 0x7003d4, 0x40}, + {1, 0x7003d5, 0xa3}, + {1, 0x7003d4, 0x41}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x42}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x43}, + {1, 0x7003d5, 0x86}, + {1, 0x7003d4, 0x44}, + {1, 0x7003d5, 0x15}, + {1, 0x7003d4, 0x45}, + {1, 0x7003d5, 0x24}, + {1, 0x7003d4, 0x46}, + {1, 0x7003d5, 0xff}, + {1, 0x7003d4, 0x47}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x48}, + {1, 0x7003d5, 0x1}, + {1, 0x7003d4, 0x49}, + {1, 0x7003d5, 0x7}, + {1, 0x7003d4, 0x4a}, + {1, 0x7003d5, 0xe5}, + {1, 0x7003d4, 0x4b}, + {1, 0x7003d5, 0x20}, + {1, 0x7003d4, 0x4c}, + {1, 0x7003d5, 0x7f}, + {1, 0x7003d4, 0x4d}, + {1, 0x7003d5, 0x57}, + {1, 0x7003d4, 0x90}, + {1, 0x7003d5, 0x55}, + {1, 0x7003d4, 0x91}, + {1, 0x7003d5, 0xd5}, + {1, 0x7003d4, 0x92}, + {1, 0x7003d5, 0x5d}, + {1, 0x7003d4, 0x93}, + {1, 0x7003d5, 0xdd}, + {1, 0x7003d4, 0x94}, + {1, 0x7003d5, 0x86}, + {1, 0x7003d4, 0x95}, + {1, 0x7003d5, 0x17}, + {1, 0x7003d4, 0x96}, + {1, 0x7003d5, 0x8e}, + {1, 0x7003d4, 0x97}, + {1, 0x7003d5, 0xaa}, + {1, 0x7003d4, 0x98}, + {1, 0x7003d5, 0x8a}, + {1, 0x7003d4, 0x99}, + {1, 0x7003d5, 0xa3}, + {1, 0x7003d4, 0x9a}, + {1, 0x7003d5, 0xde}, + {1, 0x7003d4, 0x9b}, + {1, 0x7003d5, 0xab}, + {1, 0x7003d4, 0x9c}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9d}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9e}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0x9f}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xa0}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa1}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa2}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa3}, + {1, 0x7003d5, 0x15}, + {1, 0x7003d4, 0xa4}, + {1, 0x7003d5, 0x2}, + {1, 0x7003d4, 0xa5}, + {1, 0x7003d5, 0x6}, + {1, 0x7003d4, 0xa6}, + {1, 0x7003d5, 0x0}, + {1, 0x7003d4, 0xa7}, + {1, 0x7003d5, 0x0}, + {1, 0x7003c2, 0x67}, + {4, 0x40c00c, 0x0}, + {4, 0x40c040, 0x0}, + {4, 0x40c000, 0x20000}, + {4, 0x40c010, 0x1020100}, + {1, 0x7003c4, 0x16}, + {-1, 0x7003c5, 0x17} +}; From bf8b8ab72558b490130666f1cc1f119607ff9f6f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 11 Mar 2010 02:47:08 +0100 Subject: [PATCH 034/503] Enable caches on yeeloong --- include/grub/mips/loongson.h | 57 +++++++++++++++++++++++++++ kern/mips/yeeloong/fwstart.S | 75 ++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 include/grub/mips/loongson.h diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h new file mode 100644 index 000000000..9c1ba6da9 --- /dev/null +++ b/include/grub/mips/loongson.h @@ -0,0 +1,57 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_LOONGSON_CPU_HEADER +#define GRUB_LOONGSON_CPU_HEADER 1 + +#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG $16 +#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE 0x10 +#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE 0x8 +#define GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT 6 +#define GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT 9 +#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK 0x7 +#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET 12 + +#define GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE 0 +#define GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE 9 +#define GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE 11 + +#define GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET 5 +#define GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET 5 +#define GRUB_CPU_LOONGSON_COP0_S_INDEX_BIT_OFFSET 5 + +#define GRUB_CPU_LOONGSON_CACHE_ACCELERATED 7 +#define GRUB_CPU_LOONGSON_CACHE_UNCACHED 2 +#define GRUB_CPU_LOONGSON_CACHE_CACHED 3 +#define GRUB_CPU_LOONGSON_CACHE_TYPE_MASK 7 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_SMALL 4 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG 5 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_SMALL 16 +#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_BIG 32 + +#define GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS 2 +#define GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS 2 +#define GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS 2 + +/* Fixme: determine dynamically. */ +#define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19 + +#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO $28 +#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI $29 + +#endif diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index 3dccb65fd..dc5dabc6c 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -392,6 +393,7 @@ epc: .asciz "\n\rEPC: " badvaddr: .asciz "\n\rBadVaddr: " newline: .asciz "\n\r" return_msg: .asciz "\n\rReturn address: " +caches_enabled: .asciz "Caches enabled\n\r" .p2align 3 @@ -535,6 +537,79 @@ continue: ori $t1, $t1, 0x100 sd $t1, 0x0180($t0) + /* Enable cache. */ + mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK + and $t0, $t1, $t1 + /* Set line size to 32 bytes and disabled cache. */ + ori $t0, $t0, (GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \ + | GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \ + | GRUB_CPU_LOONGSON_CACHE_ACCELERATED) + mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + + /* Invalidate all I-cache entries. */ + srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT + andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK + ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \ + - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ + - GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS)) + sll $t1, $t2, $t1 + lui $t2, 0x8000 + +1: + cache GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2) + addiu $t1, $t1, -1 + bne $t1, $zero, 1b + addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET) + + /* Invalidate all D-cache entries. */ + srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT + andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK + ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \ + - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ + - GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS)) + sll $t1, $t2, $t1 + lui $t2, 0x8000 + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI +1: + /* All four ways. */ + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2) + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2) + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2) + cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2) + addiu $t1, $t1, -1 + bne $t1, $zero, 1b + addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET) + + /* Invalidate all S-cache entries. */ + ori $t1, $zero, (1 << (GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \ + - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ + - GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS)) + lui $t2, 0x8000 + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO + mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI +1: + /* All four ways. */ + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2) + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2) + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2) + cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2) + addiu $t1, $t1, -1 + bne $t1, $zero, 1b + addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET) + + /* Finally enable cache. */ + mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK + and $t0, $t1, $t1 + ori $t0, $t0, GRUB_CPU_LOONGSON_CACHE_CACHED + mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG + + lui $a0, %hi(caches_enabled) + bal message + addiu $a0, $a0, %lo(caches_enabled) + addiu $a0, $zero, -1 addiu $a1, $zero, -1 addiu $a2, $zero, -1 From 21eecb8e83fd5bca74b1c5a694e1f89f11b4d4d6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 11 Mar 2010 03:21:10 +0100 Subject: [PATCH 035/503] Set ROM delay to 1 --- include/grub/mips/loongson.h | 4 ++++ kern/mips/yeeloong/fwstart.S | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index 9c1ba6da9..8441b6c0f 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -54,4 +54,8 @@ #define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO $28 #define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI $29 +#define GRUB_CPU_LOONGSON_LIOCFG 0xbfe00108 +#define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2 +#define GRUB_CPU_LOONGSON_ROM_DELAY_MASK 0x1f + #endif diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index dc5dabc6c..d48acabc8 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -609,6 +609,15 @@ continue: lui $a0, %hi(caches_enabled) bal message addiu $a0, $a0, %lo(caches_enabled) + + /* Set ROM delay cycles to 1. */ + lui $t0, %hi(GRUB_CPU_LOONGSON_LIOCFG) + lw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0) + addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_ROM_DELAY_MASK \ + << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET) + and $t1, $t1, $t2 + ori $t1, $t1, (1 << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET) + sw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0) addiu $a0, $zero, -1 addiu $a1, $zero, -1 From edf717f5cb173c215c48dce454264637b048de3e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 11 Mar 2010 13:59:56 +0100 Subject: [PATCH 036/503] Macroify CP0 registers --- include/grub/mips/loongson.h | 16 +++++++++++++--- kern/mips/yeeloong/fwstart.S | 10 +++++----- kern/mips/yeeloong/init.c | 3 ++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index 8441b6c0f..2c69e6c3d 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -19,7 +19,13 @@ #ifndef GRUB_LOONGSON_CPU_HEADER #define GRUB_LOONGSON_CPU_HEADER 1 -#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG $16 +#ifdef ASM_FILE +#define GRUB_CPU_REGISTER_WRAP(x) x +#else +#define GRUB_CPU_REGISTER_WRAP(x) #x +#endif + +#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG GRUB_CPU_REGISTER_WRAP($16) #define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE 0x10 #define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE 0x8 #define GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT 6 @@ -51,8 +57,12 @@ /* Fixme: determine dynamically. */ #define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19 -#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO $28 -#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI $29 +#define GRUB_CPU_LOONGSON_COP0_BADVADDR GRUB_CPU_REGISTER_WRAP($8) +#define GRUB_CPU_LOONGSON_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) +#define GRUB_CPU_LOONGSON_COP0_CAUSE GRUB_CPU_REGISTER_WRAP($13) +#define GRUB_CPU_LOONGSON_COP0_EPC GRUB_CPU_REGISTER_WRAP($14) +#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO GRUB_CPU_REGISTER_WRAP($28) +#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI GRUB_CPU_REGISTER_WRAP($29) #define GRUB_CPU_LOONGSON_LIOCFG 0xbfe00108 #define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2 diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index d48acabc8..e00da8933 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -130,8 +130,8 @@ __start: . = start + GRUB_MACHINE_FLASH_TLB_REFILL - GRUB_MACHINE_FLASH_START tlb_refill: - mfc0 $s1, $14 - mfc0 $s2, $8 + mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC + mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR move $s3, $ra lui $a0, %hi(epc) bal message @@ -170,9 +170,9 @@ cache_error: . = start + GRUB_MACHINE_FLASH_OTHER_EXCEPTION - GRUB_MACHINE_FLASH_START other_exception: - mfc0 $s0, $13 - mfc0 $s1, $14 - mfc0 $s2, $8 + mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE + mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC + mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR lui $a0, %hi(cause) bal message addiu $a0, $a0, %lo(cause) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index f35605f63..f931cdb57 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -44,7 +45,7 @@ grub_get_rtc (void) static grub_uint32_t last = 0; grub_uint32_t low; - asm volatile ("mfc0 %0, $9": "=r" (low)); + asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_TIMER_COUNT : "=r" (low)); if (low < last) high++; last = low; From d0c7485824f6052c9f425bdb821f30de892edd54 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 11 Mar 2010 15:21:06 +0100 Subject: [PATCH 037/503] Macroify serial and PCI constants --- include/grub/mips/yeeloong/serial.h | 6 ++--- kern/mips/yeeloong/fwstart.S | 34 ++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/yeeloong/serial.h index bced102b6..b22352f5a 100644 --- a/include/grub/mips/yeeloong/serial.h +++ b/include/grub/mips/yeeloong/serial.h @@ -19,11 +19,11 @@ #ifndef GRUB_MACHINE_SERIAL_HEADER #define GRUB_MACHINE_SERIAL_HEADER 1 +#define GRUB_MACHINE_SERIAL_PORT 0xbff003f8 + #ifndef ASM_FILE -#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 } +#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT } #else -#define GRUB_MACHINE_SERIAL_PORT_HI 0xbff0 -#define GRUB_MACHINE_SERIAL_PORT_LO 0x03f8 #endif #endif diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index e00da8933..838becb1b 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -47,7 +47,7 @@ __start: ori $t4, $zero, 1 lui $a0, %hi(no_cs5536) 1: - andi $t4, $t4, 0xffff + andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1) beql $t4, $zero, fatal addiu $a0, $a0, %lo(no_cs5536) sw $t4, GRUB_MACHINE_PCI_CONF_CTRL_REG_LO($t0) @@ -206,34 +206,34 @@ other_exception: we need it early. */ /* In: none. Out: none. Clobbered: $t0, $t1, $a0. */ serial_hw_init: - lui $t0, GRUB_MACHINE_SERIAL_PORT_HI + lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) /* Turn off the interrupt. */ - sb $zero, (GRUB_MACHINE_SERIAL_PORT_LO + UART_IER)($t0) + sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_IER)($t0) /* Set DLAB. */ ori $t1, $zero, UART_DLAB - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LCR)($t0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0) /* Set the baud rate 115200. */ ori $t1, $zero, 2 - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_DLL)($t0) - sb $zero, (GRUB_MACHINE_SERIAL_PORT_LO + UART_DLH)($t0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLL)($t0) + sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLH)($t0) /* Set the line status. */ ori $t1, $zero, (UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT) - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LCR)($t0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0) /* Enable the FIFO. */ ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1 - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_FCR)($t0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_FCR)($t0) /* Turn on DTR and RTS. */ ori $t1, $zero, UART_ENABLE_DTRRTS - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_MCR)($t0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_MCR)($t0) - lui $t0, 0xbff0 - addiu $t0, $t0, 0x03f8 + lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) + addiu $t0, $t0, %lo (GRUB_MACHINE_SERIAL_PORT) /* Let message return to original caller. */ lui $a0, %hi(notification_string) @@ -242,14 +242,14 @@ serial_hw_init: /* Print message on serial console. */ /* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */ message: - lui $t0, GRUB_MACHINE_SERIAL_PORT_HI + lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) 1: - lb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LSR)($t0) + lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0) andi $t1, $t1, UART_EMPTY_TRANSMITTER beq $t1, $zero, 1b nop lb $t1, 0($a0) - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0) bne $t1, $zero, 1b addiu $a0, $a0, 1 jr $ra @@ -259,10 +259,10 @@ message: In: $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2 */ printhex: - lui $t0, GRUB_MACHINE_SERIAL_PORT_HI + lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) ori $t2, $zero, 8 1: - lb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_LSR)($t0) + lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0) andi $t1, $t1, UART_EMPTY_TRANSMITTER beq $t1, $zero, 1b nop @@ -272,7 +272,7 @@ printhex: sll $a0, $a0, 4 addiu $t1, $t1, 'A'-10-'0' 2: addiu $t1, $t1, '0'+10 - sb $t1, (GRUB_MACHINE_SERIAL_PORT_LO + UART_TX)($t0) + sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0) addiu $t2, $t2, -1 bne $t2, $zero, 1b nop From 144d0913f3d60c59517f0f6005ec61f816775c48 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 11 Mar 2010 15:22:04 +0100 Subject: [PATCH 038/503] Remove leftover --- kern/mips/yeeloong/fwstart.S | 3 --- 1 file changed, 3 deletions(-) diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index 838becb1b..17fe78f40 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -232,9 +232,6 @@ serial_hw_init: ori $t1, $zero, UART_ENABLE_DTRRTS sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_MCR)($t0) - lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) - addiu $t0, $t0, %lo (GRUB_MACHINE_SERIAL_PORT) - /* Let message return to original caller. */ lui $a0, %hi(notification_string) addiu $a0, $a0, %lo(notification_string) From 8d15b3f817ab60a994df97063c96121e9c9478e7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 11 Mar 2010 20:47:22 +0100 Subject: [PATCH 039/503] Use cached address when running from ROM --- kern/mips/yeeloong/fwstart.S | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index 17fe78f40..c7ed420a4 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -618,4 +618,11 @@ continue: addiu $a0, $zero, -1 addiu $a1, $zero, -1 - addiu $a2, $zero, -1 + + /* Take advantage of cache. */ + lui $t0, %hi(cached_continue - 0x20000000) + addiu $t0, $t0, %lo(cached_continue - 0x20000000) + jr $t0 + addiu $a2, $zero, -1 + +cached_continue: \ No newline at end of file From f9ef05770a365f5ba498329eafc5bb186a64e5ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 12 Mar 2010 14:07:33 +0100 Subject: [PATCH 040/503] Shutdown and reboot on yeeloong --- conf/mips-yeeloong.rmk | 12 ++++++++++ include/grub/mips/loongson.h | 3 +++ include/grub/mips/yeeloong/ec.h | 41 +++++++++++++++++++++++++++++++++ include/grub/misc.h | 4 ++-- kern/mips/yeeloong/init.c | 17 +++++++++++--- 5 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 include/grub/mips/yeeloong/ec.h diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 91a2283e8..001bae966 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -98,6 +98,18 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For halt.mod. +pkglib_MODULES += halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +pkglib_MODULES += reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index 2c69e6c3d..c2aa276a2 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -68,4 +68,7 @@ #define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2 #define GRUB_CPU_LOONGSON_ROM_DELAY_MASK 0x1f +#define GRUB_CPU_LOONGSON_GPIOCFG 0xbfe00120 +#define GRUB_CPU_LOONGSON_SHUTDOWN_GPIO 1 + #endif diff --git a/include/grub/mips/yeeloong/ec.h b/include/grub/mips/yeeloong/ec.h new file mode 100644 index 000000000..62d1d33d9 --- /dev/null +++ b/include/grub/mips/yeeloong/ec.h @@ -0,0 +1,41 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_EC_MACHINE_HEADER +#define GRUB_EC_MACHINE_HEADER 1 + +#define GRUB_MACHINE_EC_MAGIC_PORT1 0x381 +#define GRUB_MACHINE_EC_MAGIC_PORT2 0x382 +#define GRUB_MACHINE_EC_DATA_PORT 0x383 + +#define GRUB_MACHINE_EC_MAGIC_VAL1 0xf4 +#define GRUB_MACHINE_EC_MAGIC_VAL2 0xec + +#define GRUB_MACHINE_EC_COMMAND_REBOOT 1 + +static inline void +grub_write_ec (grub_uint8_t value) +{ + grub_outb (GRUB_MACHINE_EC_MAGIC_VAL1, + GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT1); + grub_outb (GRUB_MACHINE_EC_MAGIC_VAL2, + GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT2); + grub_outb (value, GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_DATA_PORT); +} + +#endif diff --git a/include/grub/misc.h b/include/grub/misc.h index dcbafba87..1a2105549 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -298,9 +298,9 @@ void EXPORT_FUNC (grub_reboot) (void); #ifdef GRUB_MACHINE_PCBIOS /* 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); +void EXPORT_FUNC (grub_halt) (int no_apm) __attribute__ ((noreturn)); #else -void EXPORT_FUNC (grub_halt) (void); +void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); #endif #endif /* ! GRUB_MISC_HEADER */ diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index f931cdb57..8a29be8eb 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include extern void grub_video_sm712_init (void); extern void grub_video_video_init (void); @@ -165,20 +167,29 @@ grub_machine_fini (void) } void -grub_exit (void) +grub_halt (void) { + grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG) + & ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); + + grub_printf ("Shutdown failed\n"); + grub_refresh (); while (1); } void -grub_halt (void) +grub_exit (void) { - while (1); + grub_halt (); } void grub_reboot (void) { + grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); + + grub_printf ("Reboot failed\n"); + grub_refresh (); while (1); } From 5dbb0fc055bddb0083ad9b5ede4265a4c4d1629f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 12 Mar 2010 14:08:26 +0100 Subject: [PATCH 041/503] Another round of macrofication --- include/grub/cs5536.h | 11 +++++++++-- include/grub/mips/yeeloong/boot.h | 2 ++ include/grub/mips/yeeloong/pci.h | 8 ++++---- kern/mips/yeeloong/fwstart.S | 22 ++++++++++++---------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index 3f06bdb68..ec554f002 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -46,8 +46,15 @@ #define GRUB_CS5536_SMB_REG_CTRL2_ENABLE 0x1 #define GRUB_CS5536_SMB_REG_CTRL3 0x6 -#define GRUB_CS5536_LBAR_ADDR_MASK 0x000000000000fff8ULL -#define GRUB_CS5536_LBAR_ENABLE 0x0000000100000000ULL +#ifdef ASM_FILE +#define GRUB_ULL(x) x +#else +#define GRUB_ULL(x) x ## ULL +#endif + +#define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8) +#define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000) +#define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000) /* PMON-compatible LBARs. */ #define GRUB_CS5536_LBAR_GPIO 0x0b000 diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h index 6a4189ede..eda9c6ad5 100644 --- a/include/grub/mips/yeeloong/boot.h +++ b/include/grub/mips/yeeloong/boot.h @@ -26,5 +26,7 @@ #define GRUB_MACHINE_DDR2_BASE 0xaffffe00 #define GRUB_MACHINE_DDR2_REG1_HI_8BANKS 0x00000001 +#define GRUB_MACHINE_DDR2_REG_SIZE 0x8 +#define GRUB_MACHINE_DDR2_REG_STEP 0x10 #endif diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index f50cdcb35..aa5e0bbea 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -30,12 +30,12 @@ #define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 #define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR 0xbfe00118 + #ifndef ASM_FILE -#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) +#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) \ + GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) -#else -#define GRUB_MACHINE_PCI_CONF_CTRL_REG_HI 0xbfe0 -#define GRUB_MACHINE_PCI_CONF_CTRL_REG_LO 0x0118 #endif #define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 #define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index c7ed420a4..4a9a749f7 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -40,7 +40,7 @@ __start: /* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG. This way we don't need to sacrifice a register for it. */ /* We have only one bus (0). Function is 0. */ - lui $t0, GRUB_MACHINE_PCI_CONF_CTRL_REG_HI + lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE) lui $t3, %hi(GRUB_CS5536_PCIID) addiu $t3, $t3, %lo(GRUB_CS5536_PCIID) @@ -50,7 +50,7 @@ __start: andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1) beql $t4, $zero, fatal addiu $a0, $a0, %lo(no_cs5536) - sw $t4, GRUB_MACHINE_PCI_CONF_CTRL_REG_LO($t0) + sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0) lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1) bnel $t2, $t3, 1b sll $t4, $t4, 1 @@ -67,7 +67,8 @@ __start: ori $a1, $zero, GRUB_CS5536_LBAR_GPIO /* Set mask to 0xf and enabled bit to 1. */ bal wrmsr - ori $a2, $zero, 0xf001 + ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \ + | GRUB_CS5536_LBAR_ENABLE) >> 32) /* Set SMBUS LBAR. */ lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR) @@ -75,7 +76,8 @@ __start: ori $a1, $zero, GRUB_CS5536_LBAR_SMBUS /* Set mask to 0xf and enabled bit to 1. */ bal wrmsr - ori $a2, $zero, 0xf001 + ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \ + | GRUB_CS5536_LBAR_ENABLE) >> 32) lui $a0, %hi(smbus_enabled) bal message @@ -430,7 +432,7 @@ write_dumpreg: sd $t2, 0($t4) addiu $t4, $t4, 0x10 jr $ra - addiu $t6, $t6, 0x8 + addiu $t6, $t6, GRUB_MACHINE_DDR2_REG_SIZE continue: lui $t4, %hi(GRUB_MACHINE_DDR2_BASE) @@ -442,7 +444,7 @@ continue: addiu $t6, $t6, %lo(regdump) /* 1 */ - ori $a1, $a1, 0x50 + ori $a1, $a1, GRUB_SMB_RAM_START_ADDR move $t8, $zero lui $t5, 0x0001 bal read_spd @@ -455,7 +457,7 @@ continue: dsll $t8, $t8, 32 or $t5, $t5, $t8 sd $t5, 0 ($t4) - addiu $t4, $t4, 0x10 + addiu $t4, $t4, GRUB_MACHINE_DDR2_REG_STEP /* 2 */ bal write_dumpreg @@ -509,17 +511,17 @@ continue: or $t5, $t5, $v0 sd $t5, 0 ($t4) - addiu $t4, $t4, 0x10 + addiu $t4, $t4, GRUB_MACHINE_DDR2_REG_STEP ori $t7, $zero, 0x16 1: ld $t2, 0($t6) sd $t2, 0($t4) - addiu $t4, $t4, 0x10 + addiu $t4, $t4, GRUB_MACHINE_DDR2_REG_STEP addiu $t7, $t7, -1 bne $t7, $zero, 1b - addiu $t6, $t6, 0x8 + addiu $t6, $t6, GRUB_MACHINE_DDR2_REG_SIZE lui $t4, %hi(GRUB_MACHINE_DDR2_BASE) ld $t5, (%lo(GRUB_MACHINE_DDR2_BASE) + 0x30) ($t4) From 9b6e10bbbfc52a2a5f121e3b999e836114fa5417 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Mar 2010 23:18:13 +0100 Subject: [PATCH 042/503] Handle defered device registration --- disk/ata.c | 92 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/disk/ata.c b/disk/ata.c index 662fe71a7..b2291cd53 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -332,11 +332,38 @@ grub_ata_identify (struct grub_ata_device *dev) return 0; } +static grub_err_t +check_device (struct grub_ata_device *dev) +{ + grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); + grub_ata_wait (); + + /* 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. */ + grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); + grub_ata_wait (); + grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS); + grub_dprintf ("ata", "sectors=0x%x\n", sec); + if (sec != 0x5A) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected"); + + /* The above test may detect a second (slave) device + connected to a SATA controller which supports only one + (master) device. It is not safe to use the status register + READY bit to check for controller channel existence. Some + ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */ + + /* Use the IDENTIFY DEVICE command to query the device. */ + return grub_ata_identify (dev); +} + 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_err_t err; grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n", port, device, addr, addr2); @@ -352,39 +379,14 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; dev->next = NULL; - grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); - grub_ata_wait (); - - /* 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. */ - grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); - grub_ata_wait (); - grub_uint8_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; - } - - /* The above test may detect a second (slave) device - connected to a SATA controller which supports only one - (master) device. It is not safe to use the status register - READY bit to check for controller channel existence. Some - ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */ - - /* 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; + err = check_device (dev); + if (err) + grub_print_error (); + return 0; } @@ -667,6 +669,14 @@ grub_ata_iterate (int (*hook) (const char *name)) for (dev = grub_ata_devices; dev; dev = dev->next) { char devname[10]; + grub_err_t err; + + err = check_device (dev); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } if (dev->atapi) continue; @@ -685,6 +695,7 @@ static grub_err_t grub_ata_open (const char *name, grub_disk_t disk) { struct grub_ata_device *dev; + grub_err_t err; for (dev = grub_ata_devices; dev; dev = dev->next) { @@ -701,6 +712,11 @@ grub_ata_open (const char *name, grub_disk_t disk) if (dev->atapi) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); + err = check_device (dev); + + if (err) + return err; + disk->total_sectors = dev->size; disk->id = (unsigned long) dev; @@ -757,6 +773,16 @@ grub_atapi_iterate (int (*hook) (const char *name, int luns)) for (dev = grub_ata_devices; dev; dev = dev->next) { char devname[10]; + + grub_err_t err; + + err = check_device (dev); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + grub_snprintf (devname, sizeof (devname), "ata%d", dev->port * 2 + dev->device); @@ -827,6 +853,7 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) { struct grub_ata_device *dev; struct grub_ata_device *devfnd = 0; + grub_err_t err; for (dev = grub_ata_devices; dev; dev = dev->next) { @@ -846,6 +873,13 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) if (! devfnd) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); + err = check_device (devfnd); + if (err) + return err; + + if (! devfnd->atapi) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); + scsi->data = devfnd; return GRUB_ERR_NONE; From dfed5c6bb4d16a453139a058487f7767b37b5478 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Mar 2010 11:49:27 +0100 Subject: [PATCH 043/503] Removed grub_putchar --- commands/cat.c | 4 +- commands/handler.c | 2 +- commands/ls.c | 4 +- commands/minicmd.c | 8 +- commands/read.c | 2 +- font/font.c | 2 +- include/grub/charset.h | 6 ++ include/grub/misc.h | 19 +++-- include/grub/term.h | 18 ++++- kern/corecmd.c | 4 +- kern/misc.c | 151 ++++++++------------------------------ kern/rescue_reader.c | 15 ++-- kern/term.c | 30 +++----- lib/arg.c | 17 +---- lib/charset.c | 94 ++++++++++++++++++++++++ lib/crypto.c | 2 +- normal/auth.c | 4 +- normal/cmdline.c | 2 +- normal/menu.c | 4 +- normal/menu_entry.c | 3 +- normal/menu_text.c | 2 +- normal/misc.c | 12 +-- normal/term.c | 1 + term/gfxterm.c | 2 +- term/i386/pc/vga.c | 2 +- term/serial.c | 4 +- util/grub-editenv.c | 14 ++-- util/grub-fstest.c | 8 +- util/grub-probe.c | 8 +- util/grub-script-check.c | 8 +- util/i386/pc/grub-setup.c | 8 +- 31 files changed, 241 insertions(+), 219 deletions(-) diff --git a/commands/cat.c b/commands/cat.c index 3bdafc4c6..427da14e3 100644 --- a/commands/cat.c +++ b/commands/cat.c @@ -53,7 +53,7 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), unsigned char c = buf[i]; if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') - grub_putchar (c); + grub_printf ("%c", c); else { grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); @@ -67,7 +67,7 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), ; } - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); grub_file_close (file); diff --git a/commands/handler.c b/commands/handler.c index f9270972b..1e24f2091 100644 --- a/commands/handler.c +++ b/commands/handler.c @@ -36,7 +36,7 @@ grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), int list_item (grub_named_list_t item) { if (item == curr_item) - grub_putchar ('*'); + grub_xputs ("*"); grub_printf ("%s\n", item->name); diff --git a/commands/ls.c b/commands/ls.c index eb1049617..9ee0a7a31 100644 --- a/commands/ls.c +++ b/commands/ls.c @@ -57,7 +57,7 @@ grub_ls_list_devices (int longlist) } grub_device_iterate (grub_ls_print_devices); - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); return 0; @@ -233,7 +233,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) } if (grub_errno == GRUB_ERR_NONE) - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); } diff --git a/commands/minicmd.c b/commands/minicmd.c index 4ea9efead..4d0ae19b4 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -54,7 +54,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)), unsigned char c = buf[i]; if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') - grub_putchar (c); + grub_printf ("%c", c); else { grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); @@ -64,7 +64,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)), } } - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); grub_file_close (file); @@ -311,11 +311,11 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), for (dep = mod->dep; dep; dep = dep->next) { if (dep != mod->dep) - grub_putchar (','); + grub_xputs (","); grub_printf ("%s", dep->mod->name); } - grub_putchar ('\n'); + grub_xputs ("\n"); return 0; } diff --git a/commands/read.c b/commands/read.c index 8a7c4a01f..6a187fc3e 100644 --- a/commands/read.c +++ b/commands/read.c @@ -47,7 +47,7 @@ grub_getline (void) line[i] = c; if (grub_isprint (c)) - grub_putchar (c); + grub_printf ("%c", c); i++; tmp = grub_realloc (line, 1 + i + sizeof('\0')); if (! tmp) diff --git a/font/font.c b/font/font.c index 0da22d011..c4e7093d6 100644 --- a/font/font.c +++ b/font/font.c @@ -1315,7 +1315,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, /* Glyph not available in any font. Use ASCII fallback. */ if (!main_glyph) - main_glyph = ascii_glyph_lookup (code); + main_glyph = ascii_glyph_lookup (glyph_id->base); /* Glyph not available in any font. Return unknown glyph. */ if (!main_glyph) diff --git a/include/grub/charset.h b/include/grub/charset.h index fc050da24..834705a99 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -118,4 +118,10 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize); int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, grub_uint32_t **last_position); +grub_size_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); + #endif diff --git a/include/grub/misc.h b/include/grub/misc.h index dcbafba87..424026109 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -237,7 +237,19 @@ 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))); int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -int EXPORT_FUNC(grub_puts) (const char *s); + +extern void (*EXPORT_VAR (grub_xputs)) (const char *str); + +static inline int +grub_puts (const char *s) +{ + const char nl[2] = "\n"; + grub_xputs (s); + grub_xputs (nl); + + return 1; /* Cannot fail. */ +} + int EXPORT_FUNC(grub_puts_) (const char *s); void EXPORT_FUNC(grub_real_dprintf) (const char *file, const int line, @@ -253,11 +265,6 @@ char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); -grub_size_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); diff --git a/include/grub/term.h b/include/grub/term.h index 143aabe1e..319196b7b 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -63,11 +63,22 @@ grub_term_color_state; to NULL. */ /* Set when input characters shouldn't be echoed back. */ -#define GRUB_TERM_NO_ECHO (1 << 0) +#define GRUB_TERM_NO_ECHO (1 << 0) /* Set when the editing feature should be disabled. */ -#define GRUB_TERM_NO_EDIT (1 << 1) +#define GRUB_TERM_NO_EDIT (1 << 1) /* Set when the terminal cannot do fancy things. */ -#define GRUB_TERM_DUMB (1 << 2) +#define GRUB_TERM_DUMB (1 << 2) +/* Which encoding does terminal expect stream to be. */ +#define GRUB_TERM_CODE_TYPE_MASK ((1 << 5) | (1 << 4) | (1 << 3)) +/* Only ASCII characters accepted. */ +#define GRUB_TERM_CODE_TYPE_ASCII 0 +/* Expects VGA characters (ASCII + pseudographics). */ +#define GRUB_TERM_CODE_TYPE_VGA (1 << 3) +/* UTF-8 stream in logical order. Usually used for terminals + which just forward the stream to another computer. */ +#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (1 << 4) +/* UCS-4 in visual order. */ +#define GRUB_TERM_CODE_TYPE_UCS4_VISUAL ((1 << 4) | (1 << 3)) /* Bitmasks for modifier keys returned by grub_getkeystatus. */ @@ -250,7 +261,6 @@ grub_term_unregister_output (grub_term_output_t term) #define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next) #define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next) -void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, struct grub_term_output *term); int EXPORT_FUNC(grub_getkey) (void); diff --git a/kern/corecmd.c b/kern/corecmd.c index 8b8df63cb..81b4d5f25 100644 --- a/kern/corecmd.c +++ b/kern/corecmd.c @@ -121,7 +121,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), if (argc < 1) { grub_device_iterate (grub_mini_print_devices); - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); } else @@ -160,7 +160,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), else if (fs) { (fs->dir) (dev, path, grub_mini_print_files); - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); } diff --git a/kern/misc.c b/kern/misc.c index 4772e22b0..156b0650c 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -142,19 +142,6 @@ grub_printf_ (const char *fmt, ...) return ret; } -int -grub_puts (const char *s) -{ - while (*s) - { - grub_putchar (*s); - s++; - } - grub_putchar ('\n'); - - return 1; /* Cannot fail. */ -} - int grub_puts_ (const char *s) { @@ -200,13 +187,37 @@ grub_real_dprintf (const char *file, const int line, const char *condition, } } +#define PREALLOC_SIZE 255 + int grub_vprintf (const char *fmt, va_list args) { - int ret; + grub_size_t s; + static char buf[PREALLOC_SIZE + 1]; + char *curbuf = buf; - ret = grub_vsnprintf_real (0, 0, fmt, args); - return ret; + s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args); + if (s > PREALLOC_SIZE) + { + curbuf = grub_malloc (s + 1); + if (!curbuf) + { + grub_errno = GRUB_ERR_NONE; + buf[PREALLOC_SIZE - 3] = '.'; + buf[PREALLOC_SIZE - 2] = '.'; + buf[PREALLOC_SIZE - 1] = '.'; + buf[PREALLOC_SIZE] = 0; + } + else + s = grub_vsnprintf_real (curbuf, s, fmt, args); + } + + grub_xputs (curbuf); + + if (curbuf != buf) + grub_free (curbuf); + + return s; } int @@ -649,13 +660,8 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar void write_char (unsigned char ch) { - if (str) - { - if (count < max_len) - *str++ = ch; - } - else - grub_putchar (ch); + if (count < max_len) + *str++ = ch; count++; } @@ -872,8 +878,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar } } - if (str) - *str = '\0'; + *str = '\0'; return count; } @@ -906,8 +911,6 @@ grub_snprintf (char *str, grub_size_t n, const char *fmt, ...) return ret; } -#define PREALLOC_SIZE 255 - char * grub_xvasprintf (const char *fmt, va_list ap) { @@ -942,100 +945,6 @@ grub_xasprintf (const char *fmt, ...) return ret; } -/* 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 SRCEND is not NULL, then *SRCEND is set to the next byte after the - last byte used in SRC. */ -grub_size_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 */ - code = '?'; - /* Character c may be valid, don't eat it. */ - src--; - if (srcsize != (grub_size_t)-1) - srcsize++; - count = 0; - } - 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 - { - /* invalid */ - code = '?'; - count = 0; - } - } - - if (count == 0) - { - *p++ = code; - destsize--; - } - } - - if (srcend) - *srcend = src; - return p - dest; -} - /* Abort GRUB. This function does not return. */ void grub_abort (void) diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c index f573cf41f..28e43cbfd 100644 --- a/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -34,6 +34,7 @@ grub_rescue_read_line (char **line, int cont) { int c; int pos = 0; + char str[4]; grub_printf ((cont) ? "> " : "grub rescue> "); grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); @@ -44,24 +45,28 @@ grub_rescue_read_line (char **line, int cont) { if (pos < GRUB_RESCUE_BUF_SIZE - 1) { + str[0] = c; + str[1] = 0; linebuf[pos++] = c; - grub_putchar (c); + grub_xputs (str); } } else if (c == '\b') { if (pos > 0) { + str[0] = c; + str[1] = ' '; + str[2] = c; + str[3] = 0; linebuf[--pos] = 0; - grub_putchar (c); - grub_putchar (' '); - grub_putchar (c); + grub_xputs (str); } } grub_refresh (); } - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); *line = grub_strdup (linebuf); diff --git a/kern/term.c b/kern/term.c index 6e3a2b454..bd1dfc65f 100644 --- a/kern/term.c +++ b/kern/term.c @@ -50,31 +50,23 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term) (term->putchar) ('\r'); } -/* 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 void +grub_xputs_dumb (const char *str) { - static grub_size_t size = 0; - static grub_uint8_t buf[6]; - grub_uint8_t *rest; - grub_uint32_t code; - - buf[size++] = c; - - while (grub_utf8_to_ucs4 (&code, 1, buf, size, (const grub_uint8_t **) &rest) - != 0) + for (; *str; str++) { - struct grub_term_output *term; - size -= rest - buf; - grub_memmove (buf, rest, size); + grub_term_output_t term; + + char c = *str; + if ((unsigned char) c > 0x7f) + c = '?'; FOR_ACTIVE_TERM_OUTPUTS(term) - grub_putcode (code, term); - if (code == '\n' && grub_newline_hook) - grub_newline_hook (); + grub_putcode (c, term); } } +void (*grub_xputs) (const char *str) = grub_xputs_dumb; + int grub_getkey (void) { diff --git a/lib/arg.c b/lib/arg.c index 6a7bb8beb..400314d30 100644 --- a/lib/arg.c +++ b/lib/arg.c @@ -144,21 +144,8 @@ grub_arg_show_help (grub_extcmd_t cmd) } } - 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; - } + /* FIXME: add spacing back. */ + grub_xputs (_(opt->doc)); switch (opt->shortarg) { diff --git a/lib/charset.c b/lib/charset.c index f2e1b036d..52810da48 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -267,3 +267,97 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, return msg_len; } + +/* 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 SRCEND is not NULL, then *SRCEND is set to the next byte after the + last byte used in SRC. */ +grub_size_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 */ + code = '?'; + /* Character c may be valid, don't eat it. */ + src--; + if (srcsize != (grub_size_t)-1) + srcsize++; + count = 0; + } + 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 + { + /* invalid */ + code = '?'; + count = 0; + } + } + + if (count == 0) + { + *p++ = code; + destsize--; + } + } + + if (srcend) + *srcend = src; + return p - dest; +} diff --git a/lib/crypto.c b/lib/crypto.c index d11f0994f..6bd038168 100644 --- a/lib/crypto.c +++ b/lib/crypto.c @@ -445,7 +445,7 @@ grub_password_get (char buf[], unsigned buf_size) grub_memset (buf + cur_len, 0, buf_size - cur_len); - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); return (key != '\e'); diff --git a/normal/auth.c b/normal/auth.c index 156b84c37..6a7963458 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -185,13 +185,13 @@ grub_username_get (char buf[], unsigned buf_size) if (cur_len + 2 < buf_size) { buf[cur_len++] = key; - grub_putchar (key); + grub_printf ("%c", key); } } grub_memset (buf + cur_len, 0, buf_size - cur_len); - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); return (key != '\e'); diff --git a/normal/cmdline.c b/normal/cmdline.c index 05d665411..f10dc47fe 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -614,7 +614,7 @@ grub_cmdline_get (const char *prompt) grub_refresh (); } - grub_putchar ('\n'); + grub_xputs ("\n"); grub_refresh (); /* Remove leading spaces. */ diff --git a/normal/menu.c b/normal/menu.c index 07951dacc..2e722c0a6 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -42,10 +42,10 @@ grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, void grub_wait_after_message (void) { - grub_putchar ('\n'); + grub_xputs ("\n"); grub_printf_ (N_("Press any key to continue...")); (void) grub_getkey (); - grub_putchar ('\n'); + grub_xputs ("\n"); } /* Get a menu entry by its index in the entry list. */ diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 644fe90fd..74887b8ab 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -25,6 +25,7 @@ #include #include #include +#include enum update_mode { @@ -1393,7 +1394,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) grub_cls (); grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_putchar ('\n'); + grub_xputs ("\n"); grub_printf_ (N_("Press any key to continue...")); (void) grub_getkey (); } diff --git a/normal/menu_text.c b/normal/menu_text.c index b39f57512..53aed35b7 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -191,7 +191,7 @@ command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN, (grub_uint32_t) GRUB_TERM_DISP_DOWN); if (!msg_translated) return; - grub_putchar ('\n'); + grub_xputs ("\n"); grub_print_message_indented (msg_translated, STANDARD_MARGIN, STANDARD_MARGIN, term); diff --git a/normal/misc.c b/normal/misc.c index 17ba372ce..2b84b1c82 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -37,14 +37,14 @@ grub_normal_print_device_info (const char *name) p = grub_strchr (name, ','); if (p) { - grub_putchar ('\t'); + grub_xputs ("\t"); grub_printf_ (N_("Partition %s:"), name); - grub_putchar (' '); + grub_xputs (" "); } else { grub_printf_ (N_("Device %s:"), name); - grub_putchar (' '); + grub_xputs (" "); } dev = grub_device_open (name); @@ -69,7 +69,7 @@ grub_normal_print_device_info (const char *name) { if (label && grub_strlen (label)) { - grub_putchar (' '); + grub_xputs (" "); grub_printf_ (N_("- Label \"%s\""), label); } grub_free (label); @@ -84,7 +84,7 @@ grub_normal_print_device_info (const char *name) if (grub_errno == GRUB_ERR_NONE) { grub_unixtime2datetime (tm, &datetime); - grub_putchar (' '); + grub_xputs (" "); grub_printf_ (N_("- Last modification time %d-%02d-%02d " "%02d:%02d:%02d %s"), datetime.year, datetime.month, datetime.day, @@ -115,6 +115,6 @@ grub_normal_print_device_info (const char *name) grub_device_close (dev); } - grub_putchar ('\n'); + grub_xputs ("\n"); return grub_errno; } diff --git a/normal/term.c b/normal/term.c index 7bedd6799..8a974d035 100644 --- a/normal/term.c +++ b/normal/term.c @@ -23,6 +23,7 @@ #include #include #include +#include /* The amount of lines counted by the pager. */ static unsigned grub_more_lines; diff --git a/term/gfxterm.c b/term/gfxterm.c index a1409980b..e9d343317 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -840,7 +840,7 @@ grub_gfxterm_putchar (grub_uint32_t c) /* 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'); + grub_gfxterm_putchar ('\n'); /* Find position on virtual screen, and fill information. */ p = (virtual_screen.text_buffer + diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c index 402b30fe6..addb0bcbb 100644 --- a/term/i386/pc/vga.c +++ b/term/i386/pc/vga.c @@ -334,7 +334,7 @@ grub_vga_putchar (grub_uint32_t c) glyph = grub_font_get_glyph(font, c); if (xpos + char_width > TEXT_WIDTH) - grub_putchar ('\n'); + grub_vga_putchar ('\n'); p = text_buf + xpos + ypos * TEXT_WIDTH; p->code = c; diff --git a/term/serial.c b/term/serial.c index 05497ce40..1ef881f63 100644 --- a/term/serial.c +++ b/term/serial.c @@ -388,8 +388,8 @@ grub_serial_putchar (grub_uint32_t c) default: if (xpos >= TEXT_WIDTH) { - grub_putchar ('\r'); - grub_putchar ('\n'); + grub_serial_putchar ('\r'); + grub_serial_putchar ('\n'); } xpos++; break; diff --git a/util/grub-editenv.c b/util/grub-editenv.c index f21042c97..cb2eaf823 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -34,12 +34,6 @@ #define DEFAULT_ENVBLK_SIZE 1024 -void -grub_putchar (int c) -{ - putchar (c); -} - void grub_refresh (void) { @@ -52,6 +46,14 @@ grub_getkey (void) return 0; } +void +grub_xputs_real (const char *str) +{ + fputs (str, stdout); +} + +void (*grub_xputs) (const char *str) = grub_xputs_real; + char * grub_env_get (const char *name __attribute__ ((unused))) { diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c03c43451..5a773ad75 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -43,12 +43,14 @@ #include "progname.h" -void -grub_putchar (int c) +void +grub_xputs_real (const char *str) { - putchar (c); + fputs (str, stdout); } +void (*grub_xputs) (const char *str) = grub_xputs_real; + int grub_getkey (void) { diff --git a/util/grub-probe.c b/util/grub-probe.c index ba2fe4c35..782cd0367 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -58,12 +58,14 @@ enum { int print = PRINT_FS; static unsigned int argument_is_device = 0; -void -grub_putchar (int c) +void +grub_xputs_real (const char *str) { - putchar (c); + fputs (str, stdout); } +void (*grub_xputs) (const char *str) = grub_xputs_real; + int grub_getkey (void) { diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 0acf3077f..42ff2da85 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -39,12 +39,14 @@ #include "progname.h" -void -grub_putchar (int c) +void +grub_xputs_real (const char *str) { - putchar (c); + fputs (str, stdout); } +void (*grub_xputs) (const char *str) = grub_xputs_real; + int grub_getkey (void) { diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index ace577f37..1c00837e0 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -57,12 +57,14 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" -void -grub_putchar (int c) +void +grub_xputs_real (const char *str) { - putchar (c); + fputs (str, stdout); } +void (*grub_xputs) (const char *str) = grub_xputs_real; + int grub_getkey (void) { From 0a239a8211b54a38b4ed428b562f6e66d0daeab2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Mar 2010 21:14:11 +0100 Subject: [PATCH 044/503] bidi works in terminal in grub-emu --- commands/help.c | 19 +- conf/common.rmk | 7 +- font/font.c | 576 +++--------------------- include/grub/charset.h | 6 +- include/grub/font.h | 8 + include/grub/i386/vga_common.h | 6 +- include/grub/normal.h | 2 + include/grub/term.h | 11 +- include/grub/unicode.h | 18 + kern/term.c | 30 +- lib/charset.c | 783 +++++++++++++++++++++++++++++++++ normal/main.c | 7 + normal/menu_text.c | 74 ++-- term/gfxterm.c | 86 ++-- term/i386/pc/console.c | 3 +- term/i386/pc/vesafb.c | 42 +- term/i386/pc/vga.c | 26 +- term/i386/pc/vga_text.c | 1 + term/i386/vga_common.c | 54 +-- term/serial.c | 60 +-- term/terminfo.c | 12 +- util/console.c | 50 +-- util/grub-emu.c | 19 +- 23 files changed, 1101 insertions(+), 799 deletions(-) diff --git a/commands/help.c b/commands/help.c index 1181c3bfb..d56ad49a1 100644 --- a/commands/help.c +++ b/commands/help.c @@ -53,23 +53,27 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, &unicode_last_position); - FOR_ACTIVE_TERM_OUTPUTS(term) { unsigned stringwidth; grub_uint32_t *unicode_last_screen_position; - + unicode_last_screen_position = unicode_command_help; - + stringwidth = 0; - + while (unicode_last_screen_position < unicode_last_position && stringwidth < ((grub_term_width (term) / 2) - 2)) { + struct grub_unicode_glyph glyph; + unicode_last_screen_position + += grub_unicode_aglomerate_comb (unicode_last_screen_position, + unicode_last_position + - unicode_last_screen_position, + &glyph); + stringwidth - += grub_term_getcharwidth (term, - *unicode_last_screen_position); - unicode_last_screen_position++; + += grub_term_getcharwidth (term, &glyph); } grub_print_ucs4 (unicode_command_help, @@ -78,6 +82,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, grub_print_spaces (term, grub_term_width (term) / 2 - stringwidth); } + if (cnt % 2) grub_printf ("\n"); cnt++; diff --git a/conf/common.rmk b/conf/common.rmk index 80d97706e..3a7dd4f6c 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -636,7 +636,7 @@ keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS) normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal/auth.c normal/autofs.c normal/handler.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ - normal/menu_entry.c normal/menu_text.c \ + normal/menu_entry.c normal/menu_text.c lib/charset.c \ normal/misc.c normal/crypto.c normal/term.c normal/context.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -769,11 +769,6 @@ setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS) -pkglib_MODULES += charset.mod -charset_mod_SOURCES = lib/charset.c -charset_mod_CFLAGS = $(COMMON_CFLAGS) -charset_mod_LDFLAGS = $(COMMON_LDFLAGS) - pkglib_MODULES += terminal.mod terminal_mod_SOURCES = commands/terminal.c terminal_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/font/font.c b/font/font.c index c4e7093d6..a94fe8ed1 100644 --- a/font/font.c +++ b/font/font.c @@ -1135,41 +1135,13 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target, } } -static inline enum grub_comb_type -get_comb_type (grub_uint32_t c) -{ - static grub_uint8_t *comb_types = NULL; - struct grub_unicode_compact_range *cur; - - if (!comb_types) - { - unsigned i; - comb_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); - if (comb_types) - for (cur = grub_unicode_compact; cur->end; cur++) - for (i = cur->start; i <= cur->end - && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) - comb_types[i] = cur->comb_type; - else - grub_errno = GRUB_ERR_NONE; - } - - if (comb_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return comb_types[c]; - - for (cur = grub_unicode_compact; cur->end; cur++) - if (cur->start <= c && c <= cur->end) - return cur->comb_type; - - return GRUB_BIDI_TYPE_L; -} - static void blit_comb (const struct grub_unicode_glyph *glyph_id, struct grub_font_glyph *glyph, struct grub_video_signed_rect *bounds_out, struct grub_font_glyph *main_glyph, - struct grub_font_glyph **combining_glyphs) + struct grub_font_glyph **combining_glyphs, + int *device_width) { struct grub_video_signed_rect bounds; unsigned i; @@ -1203,14 +1175,23 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, { if (glyph && glyph->device_width < val) glyph->device_width = val; + if (device_width && *device_width < val) + *device_width = val; } auto void add_device_width (int val); void add_device_width (int val) { if (glyph) glyph->device_width += val; + if (device_width) + *device_width += val; } + if (glyph) + glyph->device_width = main_glyph->device_width; + if (device_width) + *device_width = main_glyph->device_width; + bounds.x = main_glyph->offset_x; bounds.y = main_glyph->offset_y; bounds.width = main_glyph->width; @@ -1231,7 +1212,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, /* CGJ is to avoid diacritics reordering. */ if (glyph_id->combining[i] == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) continue; - combtype = get_comb_type (glyph_id->combining[i]); + combtype = grub_unicode_get_comb_type (glyph_id->combining[i]); switch (combtype) { case GRUB_UNICODE_COMB_OVERLAY: @@ -1302,14 +1283,17 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, } static struct grub_font_glyph * -grub_font_construct_glyph (grub_font_t hinted_font, - const struct grub_unicode_glyph *glyph_id) +grub_font_construct_dry_run (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id, + struct grub_video_signed_rect *bounds, + struct grub_font_glyph ***combining_glyphs_out, + int *device_width) { - grub_font_t font; - struct grub_video_signed_rect bounds; struct grub_font_glyph *main_glyph; struct grub_font_glyph **combining_glyphs; - struct grub_font_glyph *glyph; + + if (combining_glyphs_out) + *combining_glyphs_out = NULL; main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base); @@ -1319,30 +1303,70 @@ grub_font_construct_glyph (grub_font_t hinted_font, /* Glyph not available in any font. Return unknown glyph. */ if (!main_glyph) - return grub_font_dup_glyph (unknown_glyph); + return NULL; + + if (device_width) + *device_width = main_glyph->device_width; if (!glyph_id->ncomb && !glyph_id->attributes) - return grub_font_dup_glyph (main_glyph); + return main_glyph; combining_glyphs = grub_malloc (sizeof (combining_glyphs[0]) * glyph_id->ncomb); if (glyph_id->ncomb && !combining_glyphs) { grub_errno = GRUB_ERR_NONE; - return grub_font_dup_glyph (main_glyph); + return main_glyph; } - font = main_glyph->font; - { unsigned i; for (i = 0; i < glyph_id->ncomb; i++) combining_glyphs[i] - = grub_font_get_glyph_with_fallback (font, glyph_id->combining[i]); + = grub_font_get_glyph_with_fallback (main_glyph->font, + glyph_id->combining[i]); } - blit_comb (glyph_id, NULL, &bounds, main_glyph, combining_glyphs); + blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs, device_width); + if (combining_glyphs_out) + *combining_glyphs_out = combining_glyphs; + else + grub_free (combining_glyphs); + return main_glyph; +} + +int +grub_font_get_constructed_device_width (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id) +{ + int ret; + struct grub_font_glyph *main_glyph; + main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL, + NULL, &ret); + if (!main_glyph) + return unknown_glyph->device_width; + return ret; +} + +struct grub_font_glyph * +grub_font_construct_glyph (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id) +{ + struct grub_font_glyph *main_glyph; + struct grub_video_signed_rect bounds; + struct grub_font_glyph *glyph; + struct grub_font_glyph **combining_glyphs; + + main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, + &bounds, &combining_glyphs, NULL); + + if (!main_glyph) + return grub_font_dup_glyph (unknown_glyph); + + if (!combining_glyphs) + return grub_font_dup_glyph (main_glyph); + glyph = grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8); if (!glyph) { @@ -1350,12 +1374,11 @@ grub_font_construct_glyph (grub_font_t hinted_font, return grub_font_dup_glyph (main_glyph); } - glyph->font = font; + glyph->font = main_glyph->font; glyph->width = bounds.width; glyph->height = bounds.height; glyph->offset_x = bounds.x; glyph->offset_y = bounds.y; - glyph->device_width = main_glyph->device_width; if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) grub_font_blit_glyph_mirror (glyph, main_glyph, @@ -1368,7 +1391,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, (glyph->height + glyph->offset_y) - (main_glyph->height + main_glyph->offset_y)); - blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs); + blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs, NULL); return glyph; } @@ -1423,465 +1446,6 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, glyph->width, glyph->height); } -static grub_uint8_t *bidi_types = NULL; - -static void -unpack_bidi (void) -{ - unsigned i; - struct grub_unicode_compact_range *cur; - - bidi_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); - if (!bidi_types) - { - grub_errno = GRUB_ERR_NONE; - return; - } - for (cur = grub_unicode_compact; cur->end; cur++) - for (i = cur->start; i <= cur->end - && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) - if (cur->bidi_mirror) - bidi_types[i] = cur->bidi_type | 0x80; - else - bidi_types[i] = cur->bidi_type | 0x00; -} - -static inline enum grub_bidi_type -get_bidi_type (grub_uint32_t c) -{ - struct grub_unicode_compact_range *cur; - - if (!bidi_types) - unpack_bidi (); - - if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return bidi_types[c] & 0x7f; - - for (cur = grub_unicode_compact; cur->end; cur++) - if (cur->start <= c && c <= cur->end) - return cur->bidi_type; - - return GRUB_BIDI_TYPE_L; -} - -static inline int -is_mirrored (grub_uint32_t c) -{ - struct grub_unicode_compact_range *cur; - - if (!bidi_types) - unpack_bidi (); - - if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return !!(bidi_types[c] & 0x80); - - for (cur = grub_unicode_compact; cur->end; cur++) - if (cur->start <= c && c <= cur->end) - return cur->bidi_mirror; - - return 0; -} - -static grub_ssize_t -grub_err_bidi_logical_to_visual (grub_uint32_t *logical, - grub_size_t logical_len, - struct grub_unicode_glyph **visual_out) -{ - enum grub_bidi_type type = GRUB_BIDI_TYPE_L; - enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; - unsigned *levels; - enum grub_bidi_type *resolved_types; - unsigned base_level; - enum override_status cur_override; - unsigned i; - unsigned stack_level[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; - enum override_status stack_override[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; - unsigned stack_depth = 0; - unsigned invalid_pushes = 0; - unsigned visual_len = 0; - unsigned run_start, run_end; - struct grub_unicode_glyph *visual; - unsigned cur_level; - - auto void push_stack (unsigned new_override, unsigned new_level); - void push_stack (unsigned new_override, unsigned new_level) - { - if (new_level > GRUB_BIDI_MAX_EXPLICIT_LEVEL) - { - invalid_pushes++; - return; - } - stack_level[stack_depth] = cur_level; - stack_override[stack_depth] = cur_override; - stack_depth++; - cur_level = new_level; - cur_override = new_override; - } - - auto void pop_stack (void); - void pop_stack (void) - { - if (invalid_pushes) - { - invalid_pushes--; - return; - } - if (!stack_depth) - return; - stack_depth--; - cur_level = stack_level[stack_depth]; - cur_override = stack_override[stack_depth]; - } - - auto void revert (unsigned start, unsigned end); - void revert (unsigned start, unsigned end) - { - struct grub_unicode_glyph t; - unsigned k, tl; - for (k = 0; k <= (end - start) / 2; k++) - { - t = visual[start+k]; - visual[start+k] = visual[end-k]; - visual[end-k] = t; - tl = levels[start+k]; - levels[start+k] = levels[end-k]; - levels[end-k] = tl; - } - } - - levels = grub_malloc (sizeof (levels[0]) * logical_len); - if (!levels) - return -1; - - resolved_types = grub_malloc (sizeof (resolved_types[0]) * logical_len); - if (!resolved_types) - { - grub_free (levels); - return -1; - } - - visual = grub_malloc (sizeof (visual[0]) * logical_len); - if (!visual) - { - grub_free (resolved_types); - grub_free (levels); - return -1; - } - - for (i = 0; i < logical_len; i++) - { - type = get_bidi_type (logical[i]); - if (type == GRUB_BIDI_TYPE_L || type == GRUB_BIDI_TYPE_AL - || type == GRUB_BIDI_TYPE_R) - break; - } - if (type == GRUB_BIDI_TYPE_R || type == GRUB_BIDI_TYPE_AL) - base_level = 1; - else - base_level = 0; - - cur_level = base_level; - cur_override = OVERRIDE_NEUTRAL; - { - unsigned last_comb_pointer = 0; - for (i = 0; i < logical_len; i++) - { - /* Variation selectors >= 17 are outside of BMP and SMP. - Handle variation selectors first to avoid potentially costly lookups. - */ - if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1 - && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16) - { - if (!visual_len) - continue; - visual[visual_len - 1].variant - = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1; - } - if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17 - && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256) - { - if (!visual_len) - continue; - visual[visual_len - 1].variant - = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17; - continue; - } - - type = get_bidi_type (logical[i]); - switch (type) - { - case GRUB_BIDI_TYPE_RLE: - push_stack (cur_override, (cur_level | 1) + 1); - break; - case GRUB_BIDI_TYPE_RLO: - push_stack (OVERRIDE_R, (cur_level | 1) + 1); - break; - case GRUB_BIDI_TYPE_LRE: - push_stack (cur_override, (cur_level & ~1) + 2); - break; - case GRUB_BIDI_TYPE_LRO: - push_stack (OVERRIDE_L, (cur_level & ~1) + 2); - break; - case GRUB_BIDI_TYPE_PDF: - pop_stack (); - break; - case GRUB_BIDI_TYPE_BN: - break; - default: - { - enum grub_comb_type comb_type; - comb_type = get_comb_type (logical[i]); - if (comb_type) - { - grub_uint32_t *n; - unsigned j; - - if (!visual_len) - break; - if (comb_type == GRUB_UNICODE_COMB_MC - || comb_type == GRUB_UNICODE_COMB_ME - || comb_type == GRUB_UNICODE_COMB_MN) - last_comb_pointer = visual[visual_len - 1].ncomb; - n = grub_realloc (visual[visual_len - 1].combining, - sizeof (grub_uint32_t) - * (visual[visual_len - 1].ncomb + 1)); - if (!n) - { - grub_errno = GRUB_ERR_NONE; - break; - } - - for (j = last_comb_pointer; - j < visual[visual_len - 1].ncomb; j++) - if (get_comb_type (visual[visual_len - 1].combining[j]) - > comb_type) - break; - grub_memmove (visual[visual_len - 1].combining + j + 1, - visual[visual_len - 1].combining + j, - (visual[visual_len - 1].ncomb - j) - * sizeof (visual[visual_len - 1].combining[0])); - visual[visual_len - 1].combining = n; - visual[visual_len - 1].combining[j] = logical[i]; - visual[visual_len - 1].ncomb++; - break; - } - last_comb_pointer = 0; - levels[visual_len] = cur_level; - if (cur_override != OVERRIDE_NEUTRAL) - resolved_types[visual_len] = - (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L - : GRUB_BIDI_TYPE_R; - else - resolved_types[visual_len] = type; - visual[visual_len].base = logical[i]; - visual[visual_len].variant = 0; - visual[visual_len].attributes = 0; - visual[visual_len].ncomb = 0; - visual[visual_len].combining = NULL; - visual_len++; - } - } - } - } - - for (run_start = 0; run_start < visual_len; run_start = run_end) - { - unsigned prev_level, next_level, cur_run_level; - unsigned last_type, last_strong_type; - for (run_end = run_start; run_end < visual_len && - levels[run_end] == levels[run_start]; run_end++); - if (run_start == 0) - prev_level = base_level; - else - prev_level = levels[run_start - 1]; - if (run_end == visual_len) - next_level = base_level; - else - next_level = levels[run_end]; - cur_run_level = levels[run_start]; - if (prev_level & 1) - last_type = GRUB_BIDI_TYPE_R; - else - last_type = GRUB_BIDI_TYPE_L; - last_strong_type = last_type; - for (i = run_start; i < run_end; i++) - { - switch (resolved_types[i]) - { - case GRUB_BIDI_TYPE_NSM: - resolved_types[i] = last_type; - break; - case GRUB_BIDI_TYPE_EN: - if (last_strong_type == GRUB_BIDI_TYPE_AL) - resolved_types[i] = GRUB_BIDI_TYPE_AN; - break; - case GRUB_BIDI_TYPE_L: - case GRUB_BIDI_TYPE_R: - last_strong_type = resolved_types[i]; - break; - case GRUB_BIDI_TYPE_ES: - if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end - && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) - resolved_types[i] = GRUB_BIDI_TYPE_EN; - else - resolved_types[i] = GRUB_BIDI_TYPE_ON; - break; - case GRUB_BIDI_TYPE_ET: - { - unsigned j; - if (last_type == GRUB_BIDI_TYPE_EN) - { - resolved_types[i] = GRUB_BIDI_TYPE_EN; - break; - } - for (j = i; j < run_end - && resolved_types[j] == GRUB_BIDI_TYPE_ET; j++); - if (j != run_end && resolved_types[j] == GRUB_BIDI_TYPE_EN) - { - for (; i < run_end - && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) - resolved_types[i] = GRUB_BIDI_TYPE_EN; - i--; - break; - } - for (; i < run_end - && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) - resolved_types[i] = GRUB_BIDI_TYPE_ON; - i--; - break; - } - break; - case GRUB_BIDI_TYPE_CS: - if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end - && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) - { - resolved_types[i] = GRUB_BIDI_TYPE_EN; - break; - } - if (last_type == GRUB_BIDI_TYPE_AN - && i + 1 < run_end - && (resolved_types[i + 1] == GRUB_BIDI_TYPE_AN - || (resolved_types[i + 1] == GRUB_BIDI_TYPE_EN - && last_strong_type == GRUB_BIDI_TYPE_AL))) - { - resolved_types[i] = GRUB_BIDI_TYPE_EN; - break; - } - resolved_types[i] = GRUB_BIDI_TYPE_ON; - break; - case GRUB_BIDI_TYPE_AL: - last_strong_type = resolved_types[i]; - resolved_types[i] = GRUB_BIDI_TYPE_R; - break; - default: /* Make GCC happy. */ - break; - } - last_type = resolved_types[i]; - if (resolved_types[i] == GRUB_BIDI_TYPE_EN - && last_strong_type == GRUB_BIDI_TYPE_L) - resolved_types[i] = GRUB_BIDI_TYPE_L; - } - if (prev_level & 1) - last_type = GRUB_BIDI_TYPE_R; - else - last_type = GRUB_BIDI_TYPE_L; - for (i = run_start; i < run_end; ) - { - unsigned j; - unsigned next_type; - for (j = i; j < run_end && - (resolved_types[j] == GRUB_BIDI_TYPE_B - || resolved_types[j] == GRUB_BIDI_TYPE_S - || resolved_types[j] == GRUB_BIDI_TYPE_WS - || resolved_types[j] == GRUB_BIDI_TYPE_ON); j++); - if (j == i) - { - if (resolved_types[i] == GRUB_BIDI_TYPE_L) - last_type = GRUB_BIDI_TYPE_L; - else - last_type = GRUB_BIDI_TYPE_R; - i++; - continue; - } - if (j == run_end) - next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; - else - { - if (resolved_types[j] == GRUB_BIDI_TYPE_L) - next_type = GRUB_BIDI_TYPE_L; - else - next_type = GRUB_BIDI_TYPE_R; - } - if (next_type == last_type) - for (; i < j; i++) - resolved_types[i] = last_type; - else - for (; i < j; i++) - resolved_types[i] = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R - : GRUB_BIDI_TYPE_L; - } - } - - for (i = 0; i < visual_len; i++) - { - if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R) - { - levels[i]++; - continue; - } - if (!(levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_AN - || resolved_types[i] == GRUB_BIDI_TYPE_EN)) - { - levels[i] += 2; - continue; - } - if ((levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_L - || resolved_types[i] == GRUB_BIDI_TYPE_AN - || resolved_types[i] == GRUB_BIDI_TYPE_EN)) - { - levels[i]++; - continue; - } - } - grub_free (resolved_types); - /* TODO: put line-wrapping here. */ - { - unsigned min_odd_level = 0xffffffff; - unsigned max_level = 0; - unsigned j; - for (i = 0; i < visual_len; i++) - { - if (levels[i] > max_level) - max_level = levels[i]; - if (levels[i] < min_odd_level && (levels[i] & 1)) - min_odd_level = levels[i]; - } - /* FIXME: can be optimized. */ - for (j = max_level; j >= min_odd_level; j--) - { - unsigned in = 0; - for (i = 0; i < visual_len; i++) - { - if (i != 0 && levels[i] >= j && levels[i-1] < j) - in = i; - if (levels[i] >= j && (i + 1 == visual_len || levels[i+1] < j)) - revert (in, i); - } - } - } - - for (i = 0; i < visual_len; i++) - if (is_mirrored (visual[i].base) && levels[i]) - visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; - - grub_free (levels); - - *visual_out = visual; - return visual_len; -} - /* 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. @@ -1902,7 +1466,7 @@ grub_font_draw_string (const char *str, grub_font_t font, if (logical_len < 0) return grub_errno; - visual_len = grub_err_bidi_logical_to_visual (logical, logical_len, &visual); + visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, 0, 0); grub_free (logical); if (visual_len < 0) return grub_errno; diff --git a/include/grub/charset.h b/include/grub/charset.h index 834705a99..6fdc2aa37 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -118,10 +118,8 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize); int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, grub_uint32_t **last_position); -grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, - grub_size_t destsize, - const grub_uint8_t *src, - grub_size_t srcsize, +grub_size_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); #endif diff --git a/include/grub/font.h b/include/grub/font.h index 54314936a..4df4c2279 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -22,6 +22,7 @@ #include #include #include +#include /* Forward declaration of opaque structure grub_font. Users only pass struct grub_font pointers to the font module functions, @@ -117,4 +118,11 @@ grub_err_t EXPORT_FUNC (grub_font_draw_string) (const char *str, grub_video_color_t color, int left_x, int baseline_y); +int +EXPORT_FUNC (grub_font_get_constructed_device_width) (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id); +struct grub_font_glyph * +EXPORT_FUNC (grub_font_construct_glyph) (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id); + #endif /* ! GRUB_FONT_HEADER */ diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h index f17fc018a..19f14ebed 100644 --- a/include/grub/i386/vga_common.h +++ b/include/grub/i386/vga_common.h @@ -25,8 +25,10 @@ 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); +void +grub_console_putchar (const struct grub_unicode_glyph *c); +grub_ssize_t +grub_console_getcharwidth (const struct grub_unicode_glyph *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); diff --git a/include/grub/normal.h b/include/grub/normal.h index fe45ddf71..b53c6c121 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -113,4 +113,6 @@ void grub_set_more (int onoff); int grub_normal_get_line_counter (void); void grub_install_newline_hook (void); +void grub_xputs_normal (const char *str); + #endif /* ! GRUB_NORMAL_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h index 319196b7b..c999b2bd3 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -39,6 +39,7 @@ #include #include #include +#include /* These are used to represent the various color states we use. */ typedef enum @@ -164,11 +165,11 @@ struct grub_term_output grub_err_t (*fini) (void); /* Put a character. C is encoded in Unicode. */ - void (*putchar) (grub_uint32_t c); + void (*putchar) (const struct grub_unicode_glyph *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); + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *c); /* Get the screen size. The return value is ((Width << 8) | Height). */ grub_uint16_t (*getwh) (void); @@ -261,8 +262,7 @@ grub_term_unregister_output (grub_term_output_t term) #define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next) #define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next) -void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, - struct grub_term_output *term); +void grub_putcode (grub_uint32_t code, struct grub_term_output *term); int EXPORT_FUNC(grub_getkey) (void); int EXPORT_FUNC(grub_checkkey) (void); int EXPORT_FUNC(grub_getkeystatus) (void); @@ -379,7 +379,8 @@ grub_term_cls (struct grub_term_output *term) } static inline grub_ssize_t -grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c) +grub_term_getcharwidth (struct grub_term_output *term, + const struct grub_unicode_glyph *c) { if (term->getcharwidth) return term->getcharwidth (c); diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 59649c3b5..1f6c4df38 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -55,6 +55,7 @@ enum grub_bidi_type enum grub_comb_type { + GRUB_UNICODE_COMB_NONE = 0, GRUB_UNICODE_COMB_OVERLAY = 1, GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, @@ -93,4 +94,21 @@ extern struct grub_unicode_compact_range grub_unicode_compact[]; /* Unicode mandates an arbitrary limit. */ #define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61 +grub_ssize_t +grub_bidi_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph **visual_out, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), + grub_size_t max_length); + +enum grub_comb_type +grub_unicode_get_comb_type (grub_uint32_t c); +grub_size_t +grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, + struct grub_unicode_glyph *out); +struct grub_unicode_glyph * +grub_unicode_glyph_from_code (grub_uint32_t code); +struct grub_unicode_glyph * +grub_unicode_glyph_dup (const struct grub_unicode_glyph *in); + #endif diff --git a/kern/term.c b/kern/term.c index bd1dfc65f..8139e8118 100644 --- a/kern/term.c +++ b/kern/term.c @@ -31,23 +31,33 @@ struct grub_term_input *grub_term_inputs; void (*grub_newline_hook) (void) = NULL; /* Put a Unicode character. */ -void -grub_putcode (grub_uint32_t code, struct grub_term_output *term) +static void +grub_putcode_dumb (grub_uint32_t code, + struct grub_term_output *term) { + struct grub_unicode_glyph c = + { + .base = code, + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + if (code == '\t' && term->getxy) { int n; n = 8 - ((term->getxy () >> 8) & 7); while (n--) - grub_putcode (' ', term); + grub_putcode_dumb (' ', term); return; } - (term->putchar) (code); + (term->putchar) (&c); if (code == '\n') - (term->putchar) ('\r'); + grub_putcode_dumb ('\r', term); } static void @@ -56,12 +66,12 @@ grub_xputs_dumb (const char *str) for (; *str; str++) { grub_term_output_t term; + grub_uint32_t code = *str; + if (code > 0x7f) + code = '?'; - char c = *str; - if ((unsigned char) c > 0x7f) - c = '?'; FOR_ACTIVE_TERM_OUTPUTS(term) - grub_putcode (c, term); + grub_putcode_dumb (code, term); } } @@ -126,7 +136,7 @@ grub_cls (void) { if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) { - grub_putcode ('\n', term); + grub_putcode_dumb ('\n', term); grub_term_refresh (term); } else diff --git a/lib/charset.c b/lib/charset.c index 52810da48..c71de7b5a 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include grub_ssize_t grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, @@ -361,3 +364,783 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, *srcend = src; return p - dest; } + +static grub_uint8_t *bidi_types = NULL; + +static void +unpack_bidi (void) +{ + unsigned i; + struct grub_unicode_compact_range *cur; + + bidi_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (!bidi_types) + { + grub_errno = GRUB_ERR_NONE; + return; + } + for (cur = grub_unicode_compact; cur->end; cur++) + for (i = cur->start; i <= cur->end + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + if (cur->bidi_mirror) + bidi_types[i] = cur->bidi_type | 0x80; + else + bidi_types[i] = cur->bidi_type | 0x00; +} + +static inline enum grub_bidi_type +get_bidi_type (grub_uint32_t c) +{ + struct grub_unicode_compact_range *cur; + + if (!bidi_types) + unpack_bidi (); + + if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return bidi_types[c] & 0x7f; + + for (cur = grub_unicode_compact; cur->end; cur++) + if (cur->start <= c && c <= cur->end) + return cur->bidi_type; + + return GRUB_BIDI_TYPE_L; +} + +static inline int +is_mirrored (grub_uint32_t c) +{ + struct grub_unicode_compact_range *cur; + + if (!bidi_types) + unpack_bidi (); + + if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return !!(bidi_types[c] & 0x80); + + for (cur = grub_unicode_compact; cur->end; cur++) + if (cur->start <= c && c <= cur->end) + return cur->bidi_mirror; + + return 0; +} + +enum grub_comb_type +grub_unicode_get_comb_type (grub_uint32_t c) +{ + static grub_uint8_t *comb_types = NULL; + struct grub_unicode_compact_range *cur; + + if (!comb_types) + { + unsigned i; + comb_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (comb_types) + for (cur = grub_unicode_compact; cur->end; cur++) + for (i = cur->start; i <= cur->end + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + comb_types[i] = cur->comb_type; + else + grub_errno = GRUB_ERR_NONE; + } + + if (comb_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return comb_types[c]; + + for (cur = grub_unicode_compact; cur->end; cur++) + if (cur->start <= c && c <= cur->end) + return cur->comb_type; + + return GRUB_UNICODE_COMB_NONE; +} + +grub_size_t +grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, + struct grub_unicode_glyph *out) +{ + int haveout = 0; + const grub_uint32_t *ptr; + unsigned last_comb_pointer = 0; + + grub_memset (out, 0, sizeof (*out)); + + for (ptr = in; ptr < in + inlen; ptr++) + { + /* Variation selectors >= 17 are outside of BMP and SMP. + Handle variation selectors first to avoid potentially costly lookups. + */ + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) + { + if (haveout) + out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1; + continue; + + } + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) + { + if (haveout) + out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17; + continue; + } + + enum grub_comb_type comb_type; + comb_type = grub_unicode_get_comb_type (*ptr); + if (comb_type) + { + grub_uint32_t *n; + unsigned j; + + if (!haveout) + continue; + + if (comb_type == GRUB_UNICODE_COMB_MC + || comb_type == GRUB_UNICODE_COMB_ME + || comb_type == GRUB_UNICODE_COMB_MN) + last_comb_pointer = out->ncomb; + n = grub_realloc (out->combining, + sizeof (grub_uint32_t) * (out->ncomb + 1)); + if (!n) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + + for (j = last_comb_pointer; j < out->ncomb; j++) + if (grub_unicode_get_comb_type (out->combining[j]) > comb_type) + break; + grub_memmove (out->combining + j + 1, + out->combining + j, + (out->ncomb - j) + * sizeof (out->combining[0])); + out->combining = n; + out->combining[j] = *ptr; + out->ncomb++; + continue; + } + if (haveout) + return ptr - in; + haveout = 1; + out->base = *ptr; + out->variant = 0; + out->attributes = 0; + out->ncomb = 0; + out->combining = NULL; + } + return ptr - in; +} + +static grub_ssize_t +grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph *visual_out, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), + grub_size_t maxwidth) +{ + enum grub_bidi_type type = GRUB_BIDI_TYPE_L; + enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; + unsigned *levels; + enum grub_bidi_type *resolved_types; + unsigned base_level; + enum override_status cur_override; + unsigned i; + unsigned stack_level[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; + enum override_status stack_override[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; + unsigned stack_depth = 0; + unsigned invalid_pushes = 0; + unsigned visual_len = 0; + unsigned run_start, run_end; + struct grub_unicode_glyph *visual; + unsigned cur_level; + + auto void push_stack (unsigned new_override, unsigned new_level); + void push_stack (unsigned new_override, unsigned new_level) + { + if (new_level > GRUB_BIDI_MAX_EXPLICIT_LEVEL) + { + invalid_pushes++; + return; + } + stack_level[stack_depth] = cur_level; + stack_override[stack_depth] = cur_override; + stack_depth++; + cur_level = new_level; + cur_override = new_override; + } + + auto void pop_stack (void); + void pop_stack (void) + { + if (invalid_pushes) + { + invalid_pushes--; + return; + } + if (!stack_depth) + return; + stack_depth--; + cur_level = stack_level[stack_depth]; + cur_override = stack_override[stack_depth]; + } + + auto void revert (unsigned start, unsigned end); + void revert (unsigned start, unsigned end) + { + struct grub_unicode_glyph t; + unsigned k, tl; + for (k = 0; k <= (end - start) / 2; k++) + { + t = visual[start+k]; + visual[start+k] = visual[end-k]; + visual[end-k] = t; + tl = levels[start+k]; + levels[start+k] = levels[end-k]; + levels[end-k] = tl; + } + } + + levels = grub_malloc (sizeof (levels[0]) * logical_len); + if (!levels) + return -1; + + resolved_types = grub_malloc (sizeof (resolved_types[0]) * logical_len); + if (!resolved_types) + { + grub_free (levels); + return -1; + } + + visual = grub_malloc (sizeof (visual[0]) * logical_len); + if (!visual) + { + grub_free (resolved_types); + grub_free (levels); + return -1; + } + + for (i = 0; i < logical_len; i++) + { + type = get_bidi_type (logical[i]); + if (type == GRUB_BIDI_TYPE_L || type == GRUB_BIDI_TYPE_AL + || type == GRUB_BIDI_TYPE_R) + break; + } + if (type == GRUB_BIDI_TYPE_R || type == GRUB_BIDI_TYPE_AL) + base_level = 1; + else + base_level = 0; + + cur_level = base_level; + cur_override = OVERRIDE_NEUTRAL; + { + const grub_uint32_t *lptr; + for (lptr = logical; lptr < logical + logical_len;) + { + grub_size_t p = grub_unicode_aglomerate_comb (lptr, logical + + logical_len - lptr, + &visual[visual_len]); + + type = get_bidi_type (visual[visual_len].base); + switch (type) + { + case GRUB_BIDI_TYPE_RLE: + push_stack (cur_override, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_RLO: + push_stack (OVERRIDE_R, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_LRE: + push_stack (cur_override, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_LRO: + push_stack (OVERRIDE_L, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_PDF: + pop_stack (); + break; + case GRUB_BIDI_TYPE_BN: + break; + default: + { + levels[visual_len] = cur_level; + if (cur_override != OVERRIDE_NEUTRAL) + resolved_types[visual_len] = + (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L + : GRUB_BIDI_TYPE_R; + else + resolved_types[visual_len] = type; + visual_len++; + } + } + lptr += p; + } + } + + for (run_start = 0; run_start < visual_len; run_start = run_end) + { + unsigned prev_level, next_level, cur_run_level; + unsigned last_type, last_strong_type; + for (run_end = run_start; run_end < visual_len && + levels[run_end] == levels[run_start]; run_end++); + if (run_start == 0) + prev_level = base_level; + else + prev_level = levels[run_start - 1]; + if (run_end == visual_len) + next_level = base_level; + else + next_level = levels[run_end]; + cur_run_level = levels[run_start]; + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + last_strong_type = last_type; + for (i = run_start; i < run_end; i++) + { + switch (resolved_types[i]) + { + case GRUB_BIDI_TYPE_NSM: + resolved_types[i] = last_type; + break; + case GRUB_BIDI_TYPE_EN: + if (last_strong_type == GRUB_BIDI_TYPE_AL) + resolved_types[i] = GRUB_BIDI_TYPE_AN; + break; + case GRUB_BIDI_TYPE_L: + case GRUB_BIDI_TYPE_R: + last_strong_type = resolved_types[i]; + break; + case GRUB_BIDI_TYPE_ES: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) + resolved_types[i] = GRUB_BIDI_TYPE_EN; + else + resolved_types[i] = GRUB_BIDI_TYPE_ON; + break; + case GRUB_BIDI_TYPE_ET: + { + unsigned j; + if (last_type == GRUB_BIDI_TYPE_EN) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + for (j = i; j < run_end + && resolved_types[j] == GRUB_BIDI_TYPE_ET; j++); + if (j != run_end && resolved_types[j] == GRUB_BIDI_TYPE_EN) + { + for (; i < run_end + && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) + resolved_types[i] = GRUB_BIDI_TYPE_EN; + i--; + break; + } + for (; i < run_end + && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) + resolved_types[i] = GRUB_BIDI_TYPE_ON; + i--; + break; + } + break; + case GRUB_BIDI_TYPE_CS: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + if (last_type == GRUB_BIDI_TYPE_AN + && i + 1 < run_end + && (resolved_types[i + 1] == GRUB_BIDI_TYPE_AN + || (resolved_types[i + 1] == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_AL))) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + resolved_types[i] = GRUB_BIDI_TYPE_ON; + break; + case GRUB_BIDI_TYPE_AL: + last_strong_type = resolved_types[i]; + resolved_types[i] = GRUB_BIDI_TYPE_R; + break; + default: /* Make GCC happy. */ + break; + } + last_type = resolved_types[i]; + if (resolved_types[i] == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_L) + resolved_types[i] = GRUB_BIDI_TYPE_L; + } + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + for (i = run_start; i < run_end; ) + { + unsigned j; + unsigned next_type; + for (j = i; j < run_end && + (resolved_types[j] == GRUB_BIDI_TYPE_B + || resolved_types[j] == GRUB_BIDI_TYPE_S + || resolved_types[j] == GRUB_BIDI_TYPE_WS + || resolved_types[j] == GRUB_BIDI_TYPE_ON); j++); + if (j == i) + { + if (resolved_types[i] == GRUB_BIDI_TYPE_L) + last_type = GRUB_BIDI_TYPE_L; + else + last_type = GRUB_BIDI_TYPE_R; + i++; + continue; + } + if (j == run_end) + next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; + else + { + if (resolved_types[j] == GRUB_BIDI_TYPE_L) + next_type = GRUB_BIDI_TYPE_L; + else + next_type = GRUB_BIDI_TYPE_R; + } + if (next_type == last_type) + for (; i < j; i++) + resolved_types[i] = last_type; + else + for (; i < j; i++) + resolved_types[i] = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R + : GRUB_BIDI_TYPE_L; + } + } + + for (i = 0; i < visual_len; i++) + { + if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R) + { + levels[i]++; + continue; + } + if (!(levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_AN + || resolved_types[i] == GRUB_BIDI_TYPE_EN)) + { + levels[i] += 2; + continue; + } + if ((levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_L + || resolved_types[i] == GRUB_BIDI_TYPE_AN + || resolved_types[i] == GRUB_BIDI_TYPE_EN)) + { + levels[i]++; + continue; + } + } + grub_free (resolved_types); + + if (!visual_len) + { + grub_free (levels); + grub_free (visual); + return 0; + } + { + struct grub_unicode_glyph *outptr = visual_out; + unsigned line_start = 0; + grub_ssize_t line_width = 0; + unsigned k; + + for (k = 0; k <= visual_len; k++) + { + grub_ssize_t last_width = 0; + if (getcharwidth && k != visual_len) + line_width += last_width = getcharwidth (&visual[k]); + if (((grub_ssize_t) maxwidth > 0 + && line_width > (grub_ssize_t) maxwidth) || k == visual_len) + { + unsigned min_odd_level = 0xffffffff; + unsigned max_level = 0; + unsigned j; + for (i = line_start; i < k; i++) + { + if (levels[i] > max_level) + max_level = levels[i]; + if (levels[i] < min_odd_level && (levels[i] & 1)) + min_odd_level = levels[i]; + } + /* FIXME: can be optimized. */ + for (j = max_level; j >= min_odd_level; j--) + { + unsigned in = 0; + for (i = line_start; i < k; i++) + { + if (i != line_start && levels[i] >= j && levels[i-1] < j) + in = i; + if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) + revert (in, i); + } + } + + for (i = line_start; i < k; i++) + if (is_mirrored (visual[i].base) && levels[i]) + visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + + grub_memcpy (outptr, &visual[line_start], + (k - line_start) * sizeof (visual[0])); + outptr += k - line_start; + if (k != visual_len) + { + grub_memset (outptr, 0, sizeof (visual[0])); + outptr->base = '\n'; + outptr++; + } + + line_start = k; + line_width = last_width; + } + } + grub_free (levels); + grub_free (visual); + + return outptr - visual_out; + } +} + +grub_ssize_t +grub_bidi_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph **visual_out, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), + grub_size_t max_length) +{ + const grub_uint32_t *line_start = logical, *ptr; + struct grub_unicode_glyph *visual_ptr; + *visual_out = visual_ptr = grub_malloc (2 * sizeof (visual_ptr[0]) + * logical_len); + for (ptr = logical; ptr <= logical + logical_len; ptr++) + { + if (ptr == logical + logical_len || *ptr == '\n') + { + grub_ssize_t ret; + ret = grub_bidi_line_logical_to_visual (line_start, + ptr - line_start, + visual_ptr, + getcharwidth, + max_length); + if (ret < 0) + { + grub_free (*visual_out); + return ret; + } + visual_ptr += ret; + line_start = ptr; + if (ptr != logical + logical_len) + { + grub_memset (visual_ptr, 0, sizeof (visual_ptr[0])); + visual_ptr->base = '\n'; + visual_ptr++; + } + } + } + return visual_ptr - *visual_out; +} + +struct grub_unicode_glyph * +grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) +{ + struct grub_unicode_glyph *out = grub_malloc (sizeof (*out)); + if (!out) + return NULL; + grub_memcpy (out, in, sizeof (*in)); + out->combining = grub_malloc (in->ncomb * sizeof (*in)); + if (!out->combining) + { + grub_free (out); + return NULL; + } + grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in)); + return out; +} + +struct grub_unicode_glyph * +grub_unicode_glyph_from_code (grub_uint32_t code) +{ + struct grub_unicode_glyph *ret; + ret = grub_malloc (sizeof (*ret)); + if (!ret) + return NULL; + + ret->base = code; + ret->variant = 0; + ret->attributes = 0; + ret->ncomb = 0; + ret->combining = 0; + + return ret; +} + +static grub_uint32_t +map_code (grub_uint32_t in, struct grub_term_output *term) +{ + if (in <= 0x7f) + return in; + + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_VGA) + { + switch (in) + { + case GRUB_TERM_DISP_LEFT: + return 0x1b; + case GRUB_TERM_DISP_UP: + return 0x18; + case GRUB_TERM_DISP_RIGHT: + return 0x1a; + case GRUB_TERM_DISP_DOWN: + return 0x19; + case GRUB_TERM_DISP_HLINE: + return 0xc4; + case GRUB_TERM_DISP_VLINE: + return 0xb3; + case GRUB_TERM_DISP_UL: + return 0xda; + case GRUB_TERM_DISP_UR: + return 0xbf; + case GRUB_TERM_DISP_LL: + return 0xc0; + case GRUB_TERM_DISP_LR: + return 0xd9; + } + return '?'; + } + else + { + /* Better than nothing. */ + switch (in) + { + case GRUB_TERM_DISP_LEFT: + return '<'; + + case GRUB_TERM_DISP_UP: + return '^'; + + case GRUB_TERM_DISP_RIGHT: + return '>'; + + case GRUB_TERM_DISP_DOWN: + return 'v'; + + case GRUB_TERM_DISP_HLINE: + return '-'; + + case GRUB_TERM_DISP_VLINE: + return '|'; + + case GRUB_TERM_DISP_UL: + case GRUB_TERM_DISP_UR: + case GRUB_TERM_DISP_LL: + case GRUB_TERM_DISP_LR: + return '+'; + + } + return '?'; + } + return in; +} + +/* Put a Unicode character. */ +void +grub_putcode (grub_uint32_t code, + struct grub_term_output *term) +{ + struct grub_unicode_glyph c = + { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + + if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE) + return; + + if (code == '\t' && term->getxy) + { + int n; + + n = 8 - ((term->getxy () >> 8) & 7); + while (n--) + grub_putcode (' ', term); + + return; + } + + c.base = map_code (code, term); + + (term->putchar) (&c); + if (code == '\n') + grub_putcode ('\r', term); +} + + +void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position, + struct grub_term_output *term) +{ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UCS4_VISUAL) + { + grub_ssize_t visual_len; + struct grub_unicode_glyph *visual; + struct grub_unicode_glyph *visual_ptr; + visual_len = grub_bidi_logical_to_visual (str, + last_position - str, + &visual, + term->getcharwidth, + grub_term_width (term)); + if (visual_len < 0) + { + grub_print_error (); + return; + } + for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) + { + struct grub_unicode_glyph glyph_r = { + .base = '\r', + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + term->putchar (visual_ptr); + if (visual_ptr->base == '\n') + term->putchar (&glyph_r); + grub_free (visual_ptr->combining); + } + grub_free (visual); + return; + } + + /* FIXME: UTF-8 terminals. */ + { + const grub_uint32_t *ptr; + for (ptr = str; ptr < last_position; ptr++) + grub_putcode (*ptr, term); + } +} + +void +grub_xputs_normal (const char *str) +{ + grub_term_output_t term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + grub_uint32_t *unicode_str, *unicode_last_position; + grub_utf8_to_ucs4_alloc (str, &unicode_str, + &unicode_last_position); + grub_print_ucs4 (unicode_str, unicode_last_position, term); + grub_free (unicode_str); + } +} diff --git a/normal/main.c b/normal/main.c index 5a5467485..334be00e9 100644 --- a/normal/main.c +++ b/normal/main.c @@ -644,10 +644,15 @@ grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)), return grub_strdup (val); } +static void (*grub_xputs_saved) (const char *str); + GRUB_MOD_INIT(normal) { grub_context_init (); + grub_xputs_saved = grub_xputs; + grub_xputs = grub_xputs_normal; + /* Normal mode shouldn't be unloaded. */ if (mod) grub_dl_ref (mod); @@ -676,6 +681,8 @@ GRUB_MOD_FINI(normal) { grub_context_fini (); + grub_xputs = grub_xputs_saved; + grub_set_history (0); grub_register_variable_hook ("pager", 0, 0); grub_fs_autoload_hook = 0; diff --git a/normal/menu_text.c b/normal/menu_text.c index 53aed35b7..1504a8e60 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -46,18 +46,6 @@ print_spaces (int number_spaces, struct grub_term_output *term) grub_putcode (' ', term); } -void -grub_print_ucs4 (const grub_uint32_t * str, - const grub_uint32_t * last_position, - struct grub_term_output *term) -{ - while (str < last_position) - { - grub_putcode (*str, term); - str++; - } -} - grub_ssize_t grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, struct grub_term_output *term) @@ -66,8 +54,9 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, while (str < last_position) { - width += grub_term_getcharwidth (term, *str); - str++; + struct grub_unicode_glyph glyph; + str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph); + width += grub_term_getcharwidth (term, &glyph); } return width; } @@ -83,8 +72,18 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right, int msg_len; - line_len = grub_term_width (term) - grub_term_getcharwidth (term, 'm') * - (margin_left + margin_right); + { + struct grub_unicode_glyph pseudo_glyph = { + .base = ' ', + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + line_len = grub_term_width (term) + - grub_term_getcharwidth (term, &pseudo_glyph) + * (margin_left + margin_right); + } msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position); @@ -252,34 +251,53 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y); + int last_printed = 0; for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0; x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) - - GRUB_TERM_MARGIN); - i++) + - GRUB_TERM_MARGIN);) { if (i < len && x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) - GRUB_TERM_MARGIN - 1)) { grub_ssize_t width; + struct grub_unicode_glyph glyph; - width = grub_term_getcharwidth (term, unicode_title[i]); + i += grub_unicode_aglomerate_comb (unicode_title + i, + len - i, &glyph); - if (x + width > (int) (GRUB_TERM_LEFT_BORDER_X + width = grub_term_getcharwidth (term, &glyph); + + if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) - GRUB_TERM_MARGIN - 1)) - grub_putcode (GRUB_TERM_DISP_RIGHT, term); - else - grub_putcode (unicode_title[i], term); - + last_printed = i; x += width; } else - { - grub_putcode (' ', term); - x++; - } + break; } + + grub_print_ucs4 (unicode_title, + unicode_title + last_printed, term); + + if (last_printed != len) + { + grub_putcode (GRUB_TERM_DISP_RIGHT, term); + struct grub_unicode_glyph pseudo_glyph = { + .base = GRUB_TERM_DISP_RIGHT, + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + x += grub_term_getcharwidth (term, &pseudo_glyph); + } + + for (; x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) + - GRUB_TERM_MARGIN); x++) + grub_putcode (' ', term); + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); grub_putcode (' ', term); diff --git a/term/gfxterm.c b/term/gfxterm.c index e9d343317..797e714d2 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -48,7 +48,7 @@ struct grub_dirty_region struct grub_colored_char { /* An Unicode codepoint. */ - grub_uint32_t code; + struct grub_unicode_glyph *code; /* Color values. */ grub_video_color_t fg_color; @@ -147,6 +147,9 @@ static unsigned char calculate_character_width (struct grub_font_glyph *glyph); static void grub_gfxterm_refresh (void); +static grub_ssize_t +grub_gfxterm_getcharwidth (const struct grub_unicode_glyph *c); + static void set_term_color (grub_uint8_t term_color) { @@ -176,7 +179,10 @@ set_term_color (grub_uint8_t term_color) static void clear_char (struct grub_colored_char *c) { - c->code = ' '; + grub_free (c->code); + c->code = grub_unicode_glyph_from_code (' '); + if (!c->code) + grub_errno = GRUB_ERR_NONE; c->fg_color = virtual_screen.fg_color; c->bg_color = virtual_screen.bg_color; c->width = 0; @@ -265,7 +271,10 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, /* Clear out text buffer. */ for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) - clear_char (&(virtual_screen.text_buffer[i])); + { + virtual_screen.text_buffer[i].code = 0; + clear_char (&(virtual_screen.text_buffer[i])); + } return grub_errno; } @@ -610,7 +619,12 @@ paint_char (unsigned cx, unsigned cy) p -= p->index; /* Get glyph for character. */ - glyph = grub_font_get_glyph (virtual_screen.font, p->code); + glyph = grub_font_construct_glyph (virtual_screen.font, p->code); + if (!glyph) + { + grub_errno = GRUB_ERR_NONE; + return; + } ascent = grub_font_get_ascent (virtual_screen.font); width = virtual_screen.normal_char_width * calculate_character_width(glyph); @@ -631,6 +645,7 @@ paint_char (unsigned cx, unsigned cy) /* Mark character to be drawn. */ dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y, width, height); + grub_free (glyph); } static inline void @@ -777,6 +792,15 @@ scroll_up (void) { unsigned int i; + /* Clear first line in text buffer. */ + for (i = 0; + i < virtual_screen.columns; + i++) + { + virtual_screen.text_buffer[i].code = 0; + clear_char (&(virtual_screen.text_buffer[i])); + } + /* Scroll text buffer with one line to up. */ grub_memmove (virtual_screen.text_buffer, virtual_screen.text_buffer + virtual_screen.columns, @@ -788,15 +812,18 @@ scroll_up (void) for (i = virtual_screen.columns * (virtual_screen.rows - 1); i < virtual_screen.columns * virtual_screen.rows; i++) - clear_char (&(virtual_screen.text_buffer[i])); + { + virtual_screen.text_buffer[i].code = 0; + clear_char (&(virtual_screen.text_buffer[i])); + } virtual_screen.total_scroll++; } static void -grub_gfxterm_putchar (grub_uint32_t c) +grub_gfxterm_putchar (const struct grub_unicode_glyph *c) { - if (c == '\a') + if (c->base == '\a') /* FIXME */ return; @@ -804,9 +831,9 @@ grub_gfxterm_putchar (grub_uint32_t c) if (virtual_screen.cursor_state) draw_cursor (0); - if (c == '\b' || c == '\n' || c == '\r') + if (c->base == '\b' || c->base == '\n' || c->base == '\r') { - switch (c) + switch (c->base) { case '\b': if (virtual_screen.cursor_x > 0) @@ -827,26 +854,30 @@ grub_gfxterm_putchar (grub_uint32_t c) } else { - struct grub_font_glyph *glyph; struct grub_colored_char *p; unsigned char char_width; - /* 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); + char_width = grub_gfxterm_getcharwidth (c); /* If we are about to exceed line length, wrap to next line. */ if (virtual_screen.cursor_x + char_width > virtual_screen.columns) - grub_gfxterm_putchar ('\n'); + { + if (virtual_screen.cursor_y >= virtual_screen.rows - 1) + scroll_up (); + else + virtual_screen.cursor_y++; + } /* 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; + grub_free (p->code); + p->code = grub_unicode_glyph_dup (c); + if (!p->code) + grub_errno = GRUB_ERR_NONE; p->fg_color = virtual_screen.fg_color; p->bg_color = virtual_screen.bg_color; p->width = char_width - 1; @@ -859,7 +890,10 @@ grub_gfxterm_putchar (grub_uint32_t c) for (i = 1; i < char_width; i++) { - p[i].code = ' '; + grub_free (p[i].code); + p[i].code = grub_unicode_glyph_from_code (' '); + if (!p[i].code) + grub_errno = GRUB_ERR_NONE; p[i].width = char_width - 1; p[i].index = i; } @@ -924,18 +958,16 @@ calculate_character_width (struct grub_font_glyph *glyph) } static grub_ssize_t -grub_gfxterm_getcharwidth (grub_uint32_t c) +grub_gfxterm_getcharwidth (const struct grub_unicode_glyph *c) { - struct grub_font_glyph *glyph; - unsigned char char_width; + int dev_width; + dev_width = grub_font_get_constructed_device_width (virtual_screen.font, c); - /* Get properties of the character. */ - glyph = grub_font_get_glyph (virtual_screen.font, c); + if (dev_width == 0) + return 1; - /* Calculate actual character width for glyph. */ - char_width = calculate_character_width (glyph); - - return char_width; + return (dev_width + (virtual_screen.normal_char_width - 1)) + / virtual_screen.normal_char_width; } static grub_uint16_t @@ -1174,7 +1206,7 @@ static struct grub_term_output grub_video_term = .getcolor = grub_virtual_screen_getcolor, .setcursor = grub_gfxterm_setcursor, .refresh = grub_gfxterm_refresh, - .flags = 0, + .flags = GRUB_TERM_CODE_TYPE_UCS4_VISUAL, .next = 0 }; diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 43cfe2f2a..5def6fca0 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -65,7 +65,8 @@ static struct grub_term_output grub_console_term_output = .setcolorstate = grub_console_setcolorstate, .setcolor = grub_console_setcolor, .getcolor = grub_console_getcolor, - .setcursor = grub_console_setcursor + .setcursor = grub_console_setcursor, + .flags = GRUB_TERM_CODE_TYPE_VGA }; void diff --git a/term/i386/pc/vesafb.c b/term/i386/pc/vesafb.c index 52694ed10..31333d7ea 100644 --- a/term/i386/pc/vesafb.c +++ b/term/i386/pc/vesafb.c @@ -214,45 +214,7 @@ grub_virtual_screen_get_glyph (grub_uint32_t code, 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); - } - } + return grub_font_get_glyph_any (code, bitmap, width); /* TODO This is wrong for the new font module. Should it be fixed? */ if (bitmap) @@ -592,7 +554,7 @@ static struct grub_term_output grub_vesafb_term = .cls = grub_vesafb_cls, .setcolorstate = grub_virtual_screen_setcolorstate, .setcursor = grub_vesafb_setcursor, - .flags = 0, + .flags = GRUB_TERM_CODE_TYPE_VGA }; GRUB_MOD_INIT(vesafb) diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c index addb0bcbb..448a773ef 100644 --- a/term/i386/pc/vga.c +++ b/term/i386/pc/vga.c @@ -287,23 +287,23 @@ scroll_up (void) } static void -grub_vga_putchar (grub_uint32_t c) +grub_vga_putchar (const struct grub_unicode_glyph *c) { #if DEBUG_VGA static int show = 1; #endif - if (c == '\a') + if (c->base == '\a') /* FIXME */ return; - if (c == '\b' || c == '\n' || c == '\r') + if (c->base == '\b' || c->base == '\n' || c->base == '\r') { /* Erase current cursor, if any. */ if (cursor_state) write_char (); - switch (c) + switch (c->base) { case '\b': if (xpos > 0) @@ -331,13 +331,19 @@ grub_vga_putchar (grub_uint32_t c) struct colored_char *p; unsigned char_width = 1; - glyph = grub_font_get_glyph(font, c); + glyph = grub_font_get_glyph(font, c->base); if (xpos + char_width > TEXT_WIDTH) - grub_vga_putchar ('\n'); + { + xpos = 0; + if (ypos >= TEXT_HEIGHT - 1) + scroll_up (); + else + ypos++; + } p = text_buf + xpos + ypos * TEXT_WIDTH; - p->code = c; + p->code = c->base; p->fg_color = fg_color; p->bg_color = bg_color; p->width = char_width - 1; @@ -387,12 +393,12 @@ grub_vga_putchar (grub_uint32_t c) } static grub_ssize_t -grub_vga_getcharwidth (grub_uint32_t c) +grub_vga_getcharwidth (const struct grub_unicode_glyph *c) { #if 0 struct grub_font_glyph glyph; - glyph = grub_font_get_glyph (c); + glyph = grub_font_get_glyph (c->base); return glyph.char_width; #else @@ -499,7 +505,7 @@ static struct grub_term_output grub_vga_term = .cls = grub_vga_cls, .setcolorstate = grub_vga_setcolorstate, .setcursor = grub_vga_setcursor, - .flags = 0, + .flags = GRUB_TERM_CODE_TYPE_UCS4_VISUAL, }; GRUB_MOD_INIT(vga) diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index f954cab43..82cc11967 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -164,6 +164,7 @@ static struct grub_term_output grub_vga_text_term = .setcolor = grub_console_setcolor, .getcolor = grub_console_getcolor, .setcursor = grub_vga_text_setcursor, + .flags = GRUB_TERM_CODE_TYPE_VGA }; GRUB_MOD_INIT(vga_text) diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c index 131b43ab6..30458b034 100644 --- a/term/i386/vga_common.c +++ b/term/i386/vga_common.c @@ -25,62 +25,14 @@ 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_putchar (const struct grub_unicode_glyph *c) { - grub_console_real_putchar (map_char (c)); + grub_console_real_putchar (c->base); } grub_ssize_t -grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused))) +grub_console_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused))) { /* For now, every printable character has the width 1. */ return 1; diff --git a/term/serial.c b/term/serial.c index 1ef881f63..d98ca4c9e 100644 --- a/term/serial.c +++ b/term/serial.c @@ -317,55 +317,12 @@ serial_hw_init (void) /* The serial version of putchar. */ static void -grub_serial_putchar (grub_uint32_t c) +grub_serial_putchar (const struct grub_unicode_glyph *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) + switch (c->base) { case '\a': break; @@ -388,19 +345,22 @@ grub_serial_putchar (grub_uint32_t c) default: if (xpos >= TEXT_WIDTH) { - grub_serial_putchar ('\r'); - grub_serial_putchar ('\n'); + xpos = 0; + if (ypos < TEXT_HEIGHT - 1) + ypos++; + serial_hw_put ('\r'); + serial_hw_put ('\n'); } xpos++; break; } } - serial_hw_put (c); + serial_hw_put (c->base); } static grub_ssize_t -grub_serial_getcharwidth (grub_uint32_t c __attribute__ ((unused))) +grub_serial_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused))) { return 1; } @@ -491,7 +451,7 @@ static struct grub_term_output grub_serial_term_output = .cls = grub_serial_cls, .setcolorstate = grub_serial_setcolorstate, .setcursor = grub_serial_setcursor, - .flags = 0, + .flags = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL, }; diff --git a/term/terminfo.c b/term/terminfo.c index 9a5979b1c..48a49f092 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -111,7 +111,17 @@ static void putstr (const char *str, grub_term_output_t oterm) { while (*str) - grub_putcode (*str++, oterm); + { + struct grub_unicode_glyph c = + { + .base = *str++, + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + oterm->putchar (&c); + } } /* Move the cursor to the given position starting with "0". */ diff --git a/util/console.c b/util/console.c index 382fd7f89..91480a810 100644 --- a/util/console.c +++ b/util/console.c @@ -64,54 +64,13 @@ static grub_uint8_t color_map[NUM_COLORS] = static int use_color; static void -grub_ncurses_putchar (grub_uint32_t c) +grub_ncurses_putchar (const struct grub_unicode_glyph *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); + addch (c->base | grub_console_attr); } static grub_ssize_t -grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused))) +grub_ncurses_getcharwidth (const struct grub_unicode_glyph * c __attribute__ ((unused))) { return 1; } @@ -367,7 +326,8 @@ static struct grub_term_output grub_ncurses_term_output = .setcolor = grub_ncurses_setcolor, .getcolor = grub_ncurses_getcolor, .setcursor = grub_ncurses_setcursor, - .refresh = grub_ncurses_refresh + .refresh = grub_ncurses_refresh, + .flags = GRUB_TERM_CODE_TYPE_ASCII }; void diff --git a/util/grub-emu.c b/util/grub-emu.c index 7d4544509..debf53b1d 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -63,6 +63,11 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_BAD_MODULE; } +void grub_hostfs_init (void); +void grub_hostfs_fini (void); +void grub_host_init (void); +void grub_host_fini (void); + grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) { @@ -75,7 +80,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) void grub_reboot (void) { - longjmp (main_env, 1); + grub_fini_all (); + grub_hostfs_fini (); + grub_host_fini (); + + grub_machine_fini (); + + exit (0); + // longjmp (main_env, 1); } void @@ -146,11 +158,6 @@ usage (int status) } -void grub_hostfs_init (void); -void grub_hostfs_fini (void); -void grub_host_init (void); -void grub_host_fini (void); - int main (int argc, char *argv[]) { From 7f837ea536c3a6cf2409984482b28460b242dddf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Mar 2010 21:34:50 +0100 Subject: [PATCH 045/503] Fixed circular dependency --- conf/common.rmk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 3a7dd4f6c..2d9f2c763 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -637,7 +637,8 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal/auth.c normal/autofs.c normal/handler.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c lib/charset.c \ - normal/misc.c normal/crypto.c normal/term.c normal/context.c + normal/misc.c normal/crypto.c normal/term.c normal/context.c \ + unidata.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -680,7 +681,7 @@ bitmap_scale_mod_CFLAGS = $(COMMON_CFLAGS) bitmap_scale_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += font.mod -font_mod_SOURCES = font/font_cmd.c font/font.c unidata.c +font_mod_SOURCES = font/font_cmd.c font/font.c font_mod_CFLAGS = $(COMMON_CFLAGS) font_mod_LDFLAGS = $(COMMON_LDFLAGS) From 53c648d2eb0bc290248918ef1ceff96e10a8f834 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Mar 2010 22:12:34 +0100 Subject: [PATCH 046/503] Break few dependencies on normal --- conf/common.rmk | 3 +- font/font.c | 75 ++--------------------------- gfxmenu/font.c | 107 +++++++++++++++++++++++++++++++++++++++++ include/grub/unicode.h | 45 +++++++++++++++-- lib/charset.c | 43 ++--------------- normal/menu_text.c | 1 + 6 files changed, 158 insertions(+), 116 deletions(-) create mode 100644 gfxmenu/font.c diff --git a/conf/common.rmk b/conf/common.rmk index 2d9f2c763..84f9c9fe4 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -496,7 +496,8 @@ gfxmenu_mod_SOURCES = \ gfxmenu/gui_progress_bar.c \ gfxmenu/gui_util.c \ gfxmenu/gui_string_util.c \ - gfxmenu/named_colors.c + gfxmenu/named_colors.c \ + gfxmenu/font.c gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS) gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/font/font.c b/font/font.c index a94fe8ed1..6209b60d2 100644 --- a/font/font.c +++ b/font/font.c @@ -924,30 +924,6 @@ 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); - if (glyph) - width += glyph->device_width; - else - width += unknown_glyph->device_width; - } - - return width; -} - /* Get the glyph for FONT corresponding to the Unicode code point CODE. Returns the ASCII glyph for the code if no other fonts are available. The glyphs are cached once loaded. */ @@ -1202,7 +1178,6 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, for (i = 0; i < glyph_id->ncomb; i++) { - enum grub_comb_type combtype; grub_int16_t space = 0; grub_int16_t centerx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x; @@ -1210,10 +1185,9 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, if (!combining_glyphs[i]) continue; /* CGJ is to avoid diacritics reordering. */ - if (glyph_id->combining[i] == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) + if (glyph_id->combining[i].code == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) continue; - combtype = grub_unicode_get_comb_type (glyph_id->combining[i]); - switch (combtype) + switch (glyph_id->combining[i].type) { case GRUB_UNICODE_COMB_OVERLAY: do_blit (combining_glyphs[i], @@ -1324,7 +1298,7 @@ grub_font_construct_dry_run (grub_font_t hinted_font, for (i = 0; i < glyph_id->ncomb; i++) combining_glyphs[i] = grub_font_get_glyph_with_fallback (main_glyph->font, - glyph_id->combining[i]); + glyph_id->combining[i].code); } blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs, device_width); @@ -1446,46 +1420,3 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, 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 *logical; - grub_ssize_t logical_len, visual_len; - struct grub_unicode_glyph *visual, *ptr; - - logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); - if (logical_len < 0) - return grub_errno; - - visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, 0, 0); - grub_free (logical); - if (visual_len < 0) - return grub_errno; - - for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++) - { - grub_err_t err; - glyph = grub_font_construct_glyph (font, ptr); - if (!glyph) - return grub_errno; - err = grub_font_draw_glyph (glyph, color, x, baseline_y); - grub_free (glyph); - if (err) - return err; - x += glyph->device_width; - } - - grub_free (visual); - - return GRUB_ERR_NONE; -} - diff --git a/gfxmenu/font.c b/gfxmenu/font.c new file mode 100644 index 000000000..9209cbaa5 --- /dev/null +++ b/gfxmenu/font.c @@ -0,0 +1,107 @@ +/* font.c - Font API and font file loader. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +/* 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 *logical; + grub_ssize_t logical_len, visual_len; + struct grub_unicode_glyph *visual, *ptr; + + logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); + if (logical_len < 0) + return grub_errno; + + visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, 0, 0); + grub_free (logical); + if (visual_len < 0) + return grub_errno; + + for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++) + { + grub_err_t err; + glyph = grub_font_construct_glyph (font, ptr); + if (!glyph) + return grub_errno; + err = grub_font_draw_glyph (glyph, color, x, baseline_y); + grub_free (glyph); + if (err) + return err; + x += glyph->device_width; + } + + grub_free (visual); + + return GRUB_ERR_NONE; +} + +/* 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 = 0; + grub_uint32_t *ptr; + grub_ssize_t logical_len; + grub_uint32_t *logical; + + logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); + if (logical_len < 0) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + + for (ptr = logical; ptr < logical + logical_len;) + { + struct grub_unicode_glyph glyph; + + ptr += grub_unicode_aglomerate_comb (ptr, + logical_len - (ptr - logical), + &glyph); + width += grub_font_get_constructed_device_width (font, &glyph); + + grub_free (glyph.combining); + } + + return width; +} diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 1f6c4df38..733bb0279 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -20,6 +20,8 @@ #define GRUB_BIDI_HEADER 1 #include +#include +#include struct grub_unicode_compact_range { @@ -78,7 +80,10 @@ struct grub_unicode_glyph grub_uint16_t variant:9; grub_uint8_t attributes:1; grub_size_t ncomb; - grub_uint32_t *combining; + struct grub_unicode_combining { + grub_uint32_t code; + enum grub_comb_type type; + } *combining; }; #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 @@ -106,9 +111,39 @@ grub_unicode_get_comb_type (grub_uint32_t c); grub_size_t grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, struct grub_unicode_glyph *out); -struct grub_unicode_glyph * -grub_unicode_glyph_from_code (grub_uint32_t code); -struct grub_unicode_glyph * -grub_unicode_glyph_dup (const struct grub_unicode_glyph *in); + +static inline struct grub_unicode_glyph * +grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) +{ + struct grub_unicode_glyph *out = grub_malloc (sizeof (*out)); + if (!out) + return NULL; + grub_memcpy (out, in, sizeof (*in)); + out->combining = grub_malloc (in->ncomb * sizeof (*in)); + if (!out->combining) + { + grub_free (out); + return NULL; + } + grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in)); + return out; +} + +static inline struct grub_unicode_glyph * +grub_unicode_glyph_from_code (grub_uint32_t code) +{ + struct grub_unicode_glyph *ret; + ret = grub_malloc (sizeof (*ret)); + if (!ret) + return NULL; + + ret->base = code; + ret->variant = 0; + ret->attributes = 0; + ret->ncomb = 0; + ret->combining = 0; + + return ret; +} #endif diff --git a/lib/charset.c b/lib/charset.c index c71de7b5a..db72a9026 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -488,7 +488,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, comb_type = grub_unicode_get_comb_type (*ptr); if (comb_type) { - grub_uint32_t *n; + struct grub_unicode_combining *n; unsigned j; if (!haveout) @@ -499,7 +499,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, || comb_type == GRUB_UNICODE_COMB_MN) last_comb_pointer = out->ncomb; n = grub_realloc (out->combining, - sizeof (grub_uint32_t) * (out->ncomb + 1)); + sizeof (n[0]) * (out->ncomb + 1)); if (!n) { grub_errno = GRUB_ERR_NONE; @@ -507,14 +507,15 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, } for (j = last_comb_pointer; j < out->ncomb; j++) - if (grub_unicode_get_comb_type (out->combining[j]) > comb_type) + if (out->combining[j].type > comb_type) break; grub_memmove (out->combining + j + 1, out->combining + j, (out->ncomb - j) * sizeof (out->combining[0])); out->combining = n; - out->combining[j] = *ptr; + out->combining[j].code = *ptr; + out->combining[j].type = comb_type; out->ncomb++; continue; } @@ -946,40 +947,6 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, return visual_ptr - *visual_out; } -struct grub_unicode_glyph * -grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) -{ - struct grub_unicode_glyph *out = grub_malloc (sizeof (*out)); - if (!out) - return NULL; - grub_memcpy (out, in, sizeof (*in)); - out->combining = grub_malloc (in->ncomb * sizeof (*in)); - if (!out->combining) - { - grub_free (out); - return NULL; - } - grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in)); - return out; -} - -struct grub_unicode_glyph * -grub_unicode_glyph_from_code (grub_uint32_t code) -{ - struct grub_unicode_glyph *ret; - ret = grub_malloc (sizeof (*ret)); - if (!ret) - return NULL; - - ret->base = code; - ret->variant = 0; - ret->attributes = 0; - ret->ncomb = 0; - ret->combining = 0; - - return ret; -} - static grub_uint32_t map_code (grub_uint32_t in, struct grub_term_output *term) { diff --git a/normal/menu_text.c b/normal/menu_text.c index 1504a8e60..5b75f29fd 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -267,6 +267,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, len - i, &glyph); width = grub_term_getcharwidth (term, &glyph); + grub_free (glyph.combining); if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) From 023e3a5ca790fd47e678b5946f0fe322d61b4eff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Mar 2010 22:17:26 +0100 Subject: [PATCH 047/503] Move charset to normal/ --- conf/common.rmk | 2 +- {lib => normal}/charset.c | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {lib => normal}/charset.c (100%) diff --git a/conf/common.rmk b/conf/common.rmk index 84f9c9fe4..acbb990da 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -637,7 +637,7 @@ keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS) normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal/auth.c normal/autofs.c normal/handler.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ - normal/menu_entry.c normal/menu_text.c lib/charset.c \ + normal/menu_entry.c normal/menu_text.c normal/charset.c \ normal/misc.c normal/crypto.c normal/term.c normal/context.c \ unidata.c normal_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/lib/charset.c b/normal/charset.c similarity index 100% rename from lib/charset.c rename to normal/charset.c From 9a3355cfde2f444dc84b2769906e84728133bf49 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 00:23:49 +0100 Subject: [PATCH 048/503] Fix EFI and IEEE1275 --- term/efi/console.c | 27 +++++++++++------ term/ieee1275/ofconsole.c | 64 ++++++++------------------------------- 2 files changed, 30 insertions(+), 61 deletions(-) diff --git a/term/efi/console.c b/term/efi/console.c index 264770cae..875a23a25 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -85,29 +85,35 @@ map_char (grub_uint32_t c) } static void -grub_console_putchar (grub_uint32_t c) +grub_console_putchar (const struct grub_unicode_glyph *c) { - grub_efi_char16_t str[2]; + grub_efi_char16_t str[2 + c->ncomb]; grub_efi_simple_text_output_interface_t *o; + unsigned i, j; 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; + if (c->base > 0xffff) + str[0] = '?'; + else + str[0] = (grub_efi_char16_t) map_char (c->base & 0xffff); + j = 1; + for (i = 0; i < c->ncomb; i++) + if (c->base < 0xffff) + str[j++] = c->combining[i].code; + str[j] = 0; /* Should this test be cached? */ - if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS) + if ((c->base > 0x7f || c->ncomb) + && 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))) +grub_console_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused))) { /* For now, every printable character has the width 1. */ return 1; @@ -351,7 +357,8 @@ static struct grub_term_output grub_console_term_output = .setcolorstate = grub_console_setcolorstate, .setcolor = grub_console_setcolor, .getcolor = grub_console_getcolor, - .setcursor = grub_console_setcursor + .setcursor = grub_console_setcursor, + .flags = GRUB_TERM_CODE_TYPE_UCS4_VISUAL }; void diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index c0f895a15..81e7e7b20 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -76,60 +76,18 @@ grub_ofconsole_writeesc (const char *str) } static void -grub_ofconsole_putchar (grub_uint32_t c) +grub_ofconsole_putchar (const struct grub_unicode_glyph *c) { char chr; - if (c > 0x7F) - { - /* Better than nothing. */ - switch (c) - { - case GRUB_TERM_DISP_LEFT: - c = '<'; - break; - - case GRUB_TERM_DISP_UP: - c = '^'; - break; + chr = c->base; - 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; - } - } - - chr = c; - - if (c == '\n') + if (chr == '\n') { grub_curr_y++; grub_curr_x = 0; } - else if (c == '\r') + else if (chr == '\r') { grub_curr_x = 0; } @@ -138,16 +96,19 @@ grub_ofconsole_putchar (grub_uint32_t c) grub_curr_x++; if (grub_curr_x >= grub_ofconsole_width) { - grub_ofconsole_putchar ('\n'); - grub_ofconsole_putchar ('\r'); - grub_curr_x++; + chr = '\n'; + grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); + chr = '\r'; + grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); + grub_curr_y++; + grub_curr_x = 1; } } grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); } static grub_ssize_t -grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused))) +grub_ofconsole_getcharwidth (const struct grub_unicode_glyph *c __attribute__((unused))) { return 1; } @@ -497,7 +458,8 @@ static struct grub_term_output grub_ofconsole_term_output = .setcolor = grub_ofconsole_setcolor, .getcolor = grub_ofconsole_getcolor, .setcursor = grub_ofconsole_setcursor, - .refresh = grub_ofconsole_refresh + .refresh = grub_ofconsole_refresh, + .flags = GRUB_TERM_CODE_TYPE_ASCII }; void From f10331edf26977b789f1de1ac4f963a8fdfeafad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 00:48:34 +0100 Subject: [PATCH 049/503] Preliminary support for UTF-8 console --- include/grub/charset.h | 4 +- normal/charset.c | 102 ++++++++++++++++++++++++++--------------- term/serial.c | 2 + 3 files changed, 69 insertions(+), 39 deletions(-) diff --git a/include/grub/charset.h b/include/grub/charset.h index 6fdc2aa37..1d79d5d2c 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -117,7 +117,9 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize); int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, grub_uint32_t **last_position); - +void +grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, + grub_uint8_t *dest, grub_size_t destsize); grub_size_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); diff --git a/normal/charset.c b/normal/charset.c index db72a9026..20c47e2ba 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -120,6 +120,45 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, return p - dest; } +/* Convert UCS-4 to UTF-8. */ +void +grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, + grub_uint8_t *dest, grub_size_t destsize) +{ + /* Keep last char for \0. */ + grub_uint8_t *destend = dest + destsize - 1; + + while (size-- && dest < destend) + { + grub_uint32_t code = *src++; + + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + if (dest + 1 >= destend) + break; + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if ((code >= 0xDC00 && code <= 0xDFFF) + || (code >= 0xD800 && code <= 0xDBFF)) + { + /* No surrogates in UCS-4... */ + *dest++ = '?'; + } + else + { + if (dest + 2 >= destend) + break; + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + *dest = 0; +} + /* Convert UCS-4 to UTF-8. */ char * grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size) @@ -127,7 +166,7 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size) grub_size_t remaining; grub_uint32_t *ptr; grub_size_t cnt = 0; - grub_uint8_t *ret, *dest; + grub_uint8_t *ret; remaining = size; ptr = src; @@ -152,34 +191,7 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size) if (!ret) return 0; - dest = ret; - remaining = size; - ptr = src; - while (remaining--) - { - grub_uint32_t code = *ptr++; - - if (code <= 0x007F) - *dest++ = code; - else if (code <= 0x07FF) - { - *dest++ = (code >> 6) | 0xC0; - *dest++ = (code & 0x3F) | 0x80; - } - else if ((code >= 0xDC00 && code <= 0xDFFF) - || (code >= 0xD800 && code <= 0xDBFF)) - { - /* No surrogates in UCS-4... */ - *dest++ = '?'; - } - else - { - *dest++ = (code >> 12) | 0xE0; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - } - *dest = 0; + grub_ucs4_to_utf8 (src, size, ret, cnt); return (char *) ret; } @@ -953,8 +965,9 @@ map_code (grub_uint32_t in, struct grub_term_output *term) if (in <= 0x7f) return in; - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_VGA) + switch (term->flags & GRUB_TERM_CODE_TYPE_MASK) { + case GRUB_TERM_CODE_TYPE_VGA: switch (in) { case GRUB_TERM_DISP_LEFT: @@ -979,9 +992,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term) return 0xd9; } return '?'; - } - else - { + case GRUB_TERM_CODE_TYPE_ASCII: /* Better than nothing. */ switch (in) { @@ -990,7 +1001,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term) case GRUB_TERM_DISP_UP: return '^'; - + case GRUB_TERM_DISP_RIGHT: return '>'; @@ -1017,8 +1028,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term) /* Put a Unicode character. */ void -grub_putcode (grub_uint32_t code, - struct grub_term_output *term) +grub_putcode (grub_uint32_t code, struct grub_term_output *term) { struct grub_unicode_glyph c = { @@ -1042,9 +1052,25 @@ grub_putcode (grub_uint32_t code, return; } - c.base = map_code (code, term); + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL) + { + grub_uint8_t str[20], *ptr; + + grub_ucs4_to_utf8 (&code, 1, str, sizeof (str)); + + for (ptr = str; *ptr; ptr++) + { + c.base = *ptr; + (term->putchar) (&c); + } + } + else + { + c.base = map_code (code, term); + (term->putchar) (&c); + } - (term->putchar) (&c); if (code == '\n') grub_putcode ('\r', term); } diff --git a/term/serial.c b/term/serial.c index d98ca4c9e..14d1f4501 100644 --- a/term/serial.c +++ b/term/serial.c @@ -343,6 +343,8 @@ grub_serial_putchar (const struct grub_unicode_glyph *c) break; default: + if ((c->base & 0xC0) == 0xC0) + break; if (xpos >= TEXT_WIDTH) { xpos = 0; From 4f501d31ae11a92a98d0481d4237001a8a0506fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 00:55:11 +0100 Subject: [PATCH 050/503] Fix length miscomputing --- term/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/term/serial.c b/term/serial.c index 14d1f4501..a1e70a79c 100644 --- a/term/serial.c +++ b/term/serial.c @@ -343,7 +343,7 @@ grub_serial_putchar (const struct grub_unicode_glyph *c) break; default: - if ((c->base & 0xC0) == 0xC0) + if ((c->base & 0xC0) == 0x80) break; if (xpos >= TEXT_WIDTH) { From 05c15154a2976d9ad5b47569c4cbae08aff6bbe6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 10:39:18 +0100 Subject: [PATCH 051/503] Visual(sic) UTF-8 support --- include/grub/term.h | 1 + normal/charset.c | 43 +++++++++++++++++++++++++++++++++++-------- term/serial.c | 2 +- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index c999b2bd3..d715755cc 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -80,6 +80,7 @@ grub_term_color_state; #define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (1 << 4) /* UCS-4 in visual order. */ #define GRUB_TERM_CODE_TYPE_UCS4_VISUAL ((1 << 4) | (1 << 3)) +#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL ((1 << 5) | (1 << 4)) /* Bitmasks for modifier keys returned by grub_getkeystatus. */ diff --git a/normal/charset.c b/normal/charset.c index 20c47e2ba..ddedeaa61 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1053,7 +1053,9 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term) } if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL) + == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + || (term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { grub_uint8_t str[20], *ptr; @@ -1081,8 +1083,10 @@ grub_print_ucs4 (const grub_uint32_t * str, const grub_uint32_t * last_position, struct grub_term_output *term) { - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UCS4_VISUAL) + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UCS4_VISUAL + || (term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { grub_ssize_t visual_len; struct grub_unicode_glyph *visual; @@ -1099,23 +1103,46 @@ grub_print_ucs4 (const grub_uint32_t * str, } for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) { - struct grub_unicode_glyph glyph_r = { - .base = '\r', + struct grub_unicode_glyph c = { .variant = 0, .attributes = 0, .ncomb = 0, .combining = 0 }; - term->putchar (visual_ptr); + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) + { + int i; + for (i = -1; i < (int) visual_ptr->ncomb; i++) + { + grub_uint8_t u8[20], *ptr; + + if (i == -1) + grub_ucs4_to_utf8 (&visual_ptr->base, 1, u8, sizeof (u8)); + else + grub_ucs4_to_utf8 (&visual_ptr->combining[i].code, + 1, u8, sizeof (u8)); + + for (ptr = u8; *ptr; ptr++) + { + c.base = *ptr; + (term->putchar) (&c); + } + } + } + else + term->putchar (visual_ptr); if (visual_ptr->base == '\n') - term->putchar (&glyph_r); + { + c.base = '\r'; + term->putchar (&c); + } grub_free (visual_ptr->combining); } grub_free (visual); return; } - /* FIXME: UTF-8 terminals. */ { const grub_uint32_t *ptr; for (ptr = str; ptr < last_position; ptr++) diff --git a/term/serial.c b/term/serial.c index a1e70a79c..53ba65ac9 100644 --- a/term/serial.c +++ b/term/serial.c @@ -453,7 +453,7 @@ static struct grub_term_output grub_serial_term_output = .cls = grub_serial_cls, .setcolorstate = grub_serial_setcolorstate, .setcursor = grub_serial_setcursor, - .flags = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL, + .flags = GRUB_TERM_CODE_TYPE_UTF8_VISUAL, }; From 97b3fbb87209e9f7fe1cd2f65ae42747f0b33678 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 10:55:06 +0100 Subject: [PATCH 052/503] Handle initial position in bidi --- gfxmenu/font.c | 3 ++- include/grub/unicode.h | 3 ++- normal/charset.c | 14 +++++++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/gfxmenu/font.c b/gfxmenu/font.c index 9209cbaa5..0c973620a 100644 --- a/gfxmenu/font.c +++ b/gfxmenu/font.c @@ -50,7 +50,8 @@ grub_font_draw_string (const char *str, grub_font_t font, if (logical_len < 0) return grub_errno; - visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, 0, 0); + visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, + 0, 0, 0); grub_free (logical); if (visual_len < 0) return grub_errno; diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 733bb0279..e7f176d0f 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -104,7 +104,8 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, grub_size_t logical_len, struct grub_unicode_glyph **visual_out, grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), - grub_size_t max_length); + grub_size_t max_width, + grub_size_t start_width); enum grub_comb_type grub_unicode_get_comb_type (grub_uint32_t c); diff --git a/normal/charset.c b/normal/charset.c index ddedeaa61..98d89ff4e 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -548,7 +548,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, grub_size_t logical_len, struct grub_unicode_glyph *visual_out, grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), - grub_size_t maxwidth) + grub_size_t maxwidth, grub_size_t startwidth) { enum grub_bidi_type type = GRUB_BIDI_TYPE_L; enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; @@ -861,7 +861,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, { struct grub_unicode_glyph *outptr = visual_out; unsigned line_start = 0; - grub_ssize_t line_width = 0; + grub_ssize_t line_width = startwidth; unsigned k; for (k = 0; k <= visual_len; k++) @@ -925,7 +925,7 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, grub_size_t logical_len, struct grub_unicode_glyph **visual_out, grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), - grub_size_t max_length) + grub_size_t max_length, grub_size_t startwidth) { const grub_uint32_t *line_start = logical, *ptr; struct grub_unicode_glyph *visual_ptr; @@ -940,7 +940,10 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, ptr - line_start, visual_ptr, getcharwidth, - max_length); + max_length, + startwidth); + startwidth = 0; + if (ret < 0) { grub_free (*visual_out); @@ -1095,7 +1098,8 @@ grub_print_ucs4 (const grub_uint32_t * str, last_position - str, &visual, term->getcharwidth, - grub_term_width (term)); + grub_term_width (term), + (term->getxy () >> 8) & 0xff); if (visual_len < 0) { grub_print_error (); From eb67952309169ad38ec9344cbd59b6f3ccb85fe3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 11:23:49 +0100 Subject: [PATCH 053/503] Separate line-wrapping function --- normal/charset.c | 170 +++++++++++++++++++++++++---------------------- 1 file changed, 92 insertions(+), 78 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index 98d89ff4e..d8a80510f 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -543,6 +543,94 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, return ptr - in; } +static grub_ssize_t +line_wrap (struct grub_unicode_glyph *visual_out, + struct grub_unicode_glyph *visual, + grub_size_t visual_len, unsigned *levels, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), + grub_size_t maxwidth, grub_size_t startwidth) +{ + struct grub_unicode_glyph *outptr = visual_out; + unsigned line_start = 0; + grub_ssize_t line_width = startwidth; + + auto void revert (unsigned start, unsigned end); + void revert (unsigned start, unsigned end) + { + struct grub_unicode_glyph t; + unsigned k, tl; + for (k = 0; k <= (end - start) / 2; k++) + { + t = visual[start + k]; + visual[start + k] = visual[end - k]; + visual[end - k] = t; + tl = levels[start + k]; + levels[start + k] = levels[end - k]; + levels[end - k] = tl; + } + } + + unsigned k; + + if (!visual_len) + return 0; + + for (k = 0; k <= visual_len; k++) + { + grub_ssize_t last_width = 0; + if (getcharwidth && k != visual_len) + line_width += last_width = getcharwidth (&visual[k]); + if (((grub_ssize_t) maxwidth > 0 + && line_width > (grub_ssize_t) maxwidth) || k == visual_len) + { + unsigned min_odd_level = 0xffffffff; + unsigned max_level = 0; + unsigned i, j; + for (i = line_start; i < k; i++) + { + if (levels[i] > max_level) + max_level = levels[i]; + if (levels[i] < min_odd_level && (levels[i] & 1)) + min_odd_level = levels[i]; + } + + if (levels) + { + /* FIXME: can be optimized. */ + for (j = max_level; j >= min_odd_level; j--) + { + unsigned in = 0; + for (i = line_start; i < k; i++) + { + if (i != line_start && levels[i] >= j && levels[i-1] < j) + in = i; + if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) + revert (in, i); + } + } + + for (i = line_start; i < k; i++) + if (is_mirrored (visual[i].base) && levels[i]) + visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + } + + outptr += k - line_start; + if (k != visual_len) + { + grub_memset (outptr, 0, sizeof (visual[0])); + outptr->base = '\n'; + outptr++; + } + + line_start = k; + line_width = last_width; + } + } + + return outptr - visual_out; +} + + static grub_ssize_t grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, grub_size_t logical_len, @@ -596,22 +684,6 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, cur_override = stack_override[stack_depth]; } - auto void revert (unsigned start, unsigned end); - void revert (unsigned start, unsigned end) - { - struct grub_unicode_glyph t; - unsigned k, tl; - for (k = 0; k <= (end - start) / 2; k++) - { - t = visual[start+k]; - visual[start+k] = visual[end-k]; - visual[end-k] = t; - tl = levels[start+k]; - levels[start+k] = levels[end-k]; - levels[end-k] = tl; - } - } - levels = grub_malloc (sizeof (levels[0]) * logical_len); if (!levels) return -1; @@ -852,71 +924,13 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, } grub_free (resolved_types); - if (!visual_len) - { - grub_free (levels); - grub_free (visual); - return 0; - } { - struct grub_unicode_glyph *outptr = visual_out; - unsigned line_start = 0; - grub_ssize_t line_width = startwidth; - unsigned k; - - for (k = 0; k <= visual_len; k++) - { - grub_ssize_t last_width = 0; - if (getcharwidth && k != visual_len) - line_width += last_width = getcharwidth (&visual[k]); - if (((grub_ssize_t) maxwidth > 0 - && line_width > (grub_ssize_t) maxwidth) || k == visual_len) - { - unsigned min_odd_level = 0xffffffff; - unsigned max_level = 0; - unsigned j; - for (i = line_start; i < k; i++) - { - if (levels[i] > max_level) - max_level = levels[i]; - if (levels[i] < min_odd_level && (levels[i] & 1)) - min_odd_level = levels[i]; - } - /* FIXME: can be optimized. */ - for (j = max_level; j >= min_odd_level; j--) - { - unsigned in = 0; - for (i = line_start; i < k; i++) - { - if (i != line_start && levels[i] >= j && levels[i-1] < j) - in = i; - if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) - revert (in, i); - } - } - - for (i = line_start; i < k; i++) - if (is_mirrored (visual[i].base) && levels[i]) - visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; - - grub_memcpy (outptr, &visual[line_start], - (k - line_start) * sizeof (visual[0])); - outptr += k - line_start; - if (k != visual_len) - { - grub_memset (outptr, 0, sizeof (visual[0])); - outptr->base = '\n'; - outptr++; - } - - line_start = k; - line_width = last_width; - } - } + grub_ssize_t ret; + ret = line_wrap (visual_out, visual, visual_len, levels, + getcharwidth, maxwidth, startwidth); grub_free (levels); grub_free (visual); - - return outptr - visual_out; + return ret; } } From cacd173d3eb9ca0a6128840bafd03d28d2173c9b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 11:31:05 +0100 Subject: [PATCH 054/503] Fix linewrapper when levels=NULL --- normal/charset.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index d8a80510f..490a70383 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -553,25 +553,24 @@ line_wrap (struct grub_unicode_glyph *visual_out, struct grub_unicode_glyph *outptr = visual_out; unsigned line_start = 0; grub_ssize_t line_width = startwidth; + unsigned k; auto void revert (unsigned start, unsigned end); void revert (unsigned start, unsigned end) { struct grub_unicode_glyph t; - unsigned k, tl; - for (k = 0; k <= (end - start) / 2; k++) + unsigned i, tl; + for (i = 0; i <= (end - start) / 2; i++) { - t = visual[start + k]; - visual[start + k] = visual[end - k]; - visual[end - k] = t; - tl = levels[start + k]; - levels[start + k] = levels[end - k]; - levels[end - k] = tl; + t = visual[start + i]; + visual[start + i] = visual[end - i]; + visual[end - i] = t; + tl = levels[start + i]; + levels[start + i] = levels[end - i]; + levels[end - i] = tl; } } - unsigned k; - if (!visual_len) return 0; @@ -582,20 +581,22 @@ line_wrap (struct grub_unicode_glyph *visual_out, line_width += last_width = getcharwidth (&visual[k]); if (((grub_ssize_t) maxwidth > 0 && line_width > (grub_ssize_t) maxwidth) || k == visual_len) - { - unsigned min_odd_level = 0xffffffff; - unsigned max_level = 0; - unsigned i, j; - for (i = line_start; i < k; i++) - { - if (levels[i] > max_level) - max_level = levels[i]; - if (levels[i] < min_odd_level && (levels[i] & 1)) - min_odd_level = levels[i]; - } - + { if (levels) { + unsigned min_odd_level = 0xffffffff; + unsigned max_level = 0; + unsigned j; + + unsigned i; + for (i = line_start; i < k; i++) + { + if (levels[i] > max_level) + max_level = levels[i]; + if (levels[i] < min_odd_level && (levels[i] & 1)) + min_odd_level = levels[i]; + } + /* FIXME: can be optimized. */ for (j = max_level; j >= min_odd_level; j--) { From f588f1c8b6a890bf04207be34669120ebc9d3e49 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 14:13:32 +0100 Subject: [PATCH 055/503] Add simple line wrapping --- commands/help.c | 2 +- include/grub/normal.h | 8 ++- normal/charset.c | 144 ++++++++++++++++++++++++++++-------------- normal/main.c | 2 +- normal/menu_text.c | 35 +++------- 5 files changed, 113 insertions(+), 78 deletions(-) diff --git a/commands/help.c b/commands/help.c index d56ad49a1..b9e1a9145 100644 --- a/commands/help.c +++ b/commands/help.c @@ -77,7 +77,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, } grub_print_ucs4 (unicode_command_help, - unicode_last_screen_position, term); + unicode_last_screen_position, 0, 0, term); if (!(cnt % 2)) grub_print_spaces (term, grub_term_width (term) / 2 - stringwidth); diff --git a/include/grub/normal.h b/include/grub/normal.h index b53c6c121..6ec14d31a 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -77,9 +77,11 @@ void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); /* Defined in `menu_text.c'. */ void grub_wait_after_message (void); -void grub_print_ucs4 (const grub_uint32_t * str, - const grub_uint32_t * last_position, - struct grub_term_output *term); +void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term); grub_ssize_t grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, struct grub_term_output *term); diff --git a/normal/charset.c b/normal/charset.c index 490a70383..383f2c458 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -544,11 +544,11 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, } static grub_ssize_t -line_wrap (struct grub_unicode_glyph *visual_out, - struct grub_unicode_glyph *visual, - grub_size_t visual_len, unsigned *levels, - grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), - grub_size_t maxwidth, grub_size_t startwidth) +bidi_line_wrap (struct grub_unicode_glyph *visual_out, + struct grub_unicode_glyph *visual, + grub_size_t visual_len, unsigned *levels, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), + grub_size_t maxwidth, grub_size_t startwidth) { struct grub_unicode_glyph *outptr = visual_out; unsigned line_start = 0; @@ -582,38 +582,35 @@ line_wrap (struct grub_unicode_glyph *visual_out, if (((grub_ssize_t) maxwidth > 0 && line_width > (grub_ssize_t) maxwidth) || k == visual_len) { - if (levels) + unsigned min_odd_level = 0xffffffff; + unsigned max_level = 0; + unsigned j; + + unsigned i; + for (i = line_start; i < k; i++) { - unsigned min_odd_level = 0xffffffff; - unsigned max_level = 0; - unsigned j; - - unsigned i; - for (i = line_start; i < k; i++) - { - if (levels[i] > max_level) - max_level = levels[i]; - if (levels[i] < min_odd_level && (levels[i] & 1)) - min_odd_level = levels[i]; - } - - /* FIXME: can be optimized. */ - for (j = max_level; j >= min_odd_level; j--) - { - unsigned in = 0; - for (i = line_start; i < k; i++) - { - if (i != line_start && levels[i] >= j && levels[i-1] < j) - in = i; - if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) - revert (in, i); - } - } - - for (i = line_start; i < k; i++) - if (is_mirrored (visual[i].base) && levels[i]) - visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + if (levels[i] > max_level) + max_level = levels[i]; + if (levels[i] < min_odd_level && (levels[i] & 1)) + min_odd_level = levels[i]; } + + /* FIXME: can be optimized. */ + for (j = max_level; j >= min_odd_level; j--) + { + unsigned in = 0; + for (i = line_start; i < k; i++) + { + if (i != line_start && levels[i] >= j && levels[i-1] < j) + in = i; + if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) + revert (in, i); + } + } + + for (i = line_start; i < k; i++) + if (is_mirrored (visual[i].base) && levels[i]) + visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; outptr += k - line_start; if (k != visual_len) @@ -927,8 +924,8 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, { grub_ssize_t ret; - ret = line_wrap (visual_out, visual, visual_len, levels, - getcharwidth, maxwidth, startwidth); + ret = bidi_line_wrap (visual_out, visual, visual_len, levels, + getcharwidth, maxwidth, startwidth); grub_free (levels); grub_free (visual); return ret; @@ -1056,7 +1053,11 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term) .combining = 0 }; - if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE) + if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE + && ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && (term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_VISUAL)) return; if (code == '\t' && term->getxy) @@ -1095,12 +1096,33 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term) grub_putcode ('\r', term); } - void grub_print_ucs4 (const grub_uint32_t * str, const grub_uint32_t * last_position, + int margin_left, int margin_right, struct grub_term_output *term) { + grub_size_t line_len; + grub_ssize_t startwidth; + + { + struct grub_unicode_glyph space_glyph = { + .base = ' ', + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + line_len = grub_term_width (term) + - grub_term_getcharwidth (term, &space_glyph) + * (margin_left + margin_right) - 1; + } + + if (((term->getxy () >> 8) & 0xff) < margin_left) + grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff)); + + startwidth = ((term->getxy () >> 8) & 0xff) - margin_left; + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UCS4_VISUAL || (term->flags & GRUB_TERM_CODE_TYPE_MASK) @@ -1109,12 +1131,9 @@ grub_print_ucs4 (const grub_uint32_t * str, grub_ssize_t visual_len; struct grub_unicode_glyph *visual; struct grub_unicode_glyph *visual_ptr; - visual_len = grub_bidi_logical_to_visual (str, - last_position - str, - &visual, - term->getcharwidth, - grub_term_width (term), - (term->getxy () >> 8) & 0xff); + visual_len = grub_bidi_logical_to_visual (str, last_position - str, + &visual, term->getcharwidth, + line_len, startwidth); if (visual_len < 0) { grub_print_error (); @@ -1128,6 +1147,8 @@ grub_print_ucs4 (const grub_uint32_t * str, .ncomb = 0, .combining = 0 }; + if (visual_ptr->base == '\n') + grub_print_spaces (term, margin_right); if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { @@ -1155,6 +1176,7 @@ grub_print_ucs4 (const grub_uint32_t * str, { c.base = '\r'; term->putchar (&c); + grub_print_spaces (term, margin_left); } grub_free (visual_ptr->combining); } @@ -1164,8 +1186,36 @@ grub_print_ucs4 (const grub_uint32_t * str, { const grub_uint32_t *ptr; + grub_ssize_t line_width = startwidth; + grub_ssize_t maxwidth = line_len; + for (ptr = str; ptr < last_position; ptr++) - grub_putcode (*ptr, term); + { + struct grub_unicode_glyph c = { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + grub_ssize_t last_width = 0; + if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) + { + c.base = *ptr; + line_width += last_width = term->getcharwidth (&c); + } + + if (line_width > maxwidth || *ptr == '\n') + { + grub_print_spaces (term, margin_right); + grub_putcode ('\n', term); + grub_putcode ('\r', term); + line_width = last_width; + grub_print_spaces (term, margin_left); + } + + if (*ptr != '\n') + grub_putcode (*ptr, term); + } } } @@ -1179,7 +1229,7 @@ grub_xputs_normal (const char *str) grub_uint32_t *unicode_str, *unicode_last_position; grub_utf8_to_ucs4_alloc (str, &unicode_str, &unicode_last_position); - grub_print_ucs4 (unicode_str, unicode_last_position, term); + grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); grub_free (unicode_str); } } diff --git a/normal/main.c b/normal/main.c index 334be00e9..ab28609cd 100644 --- a/normal/main.c +++ b/normal/main.c @@ -429,7 +429,7 @@ grub_normal_init_page (struct grub_term_output *term) posx = (grub_term_width (term) - posx) / 2; grub_term_gotoxy (term, posx, 1); - grub_print_ucs4 (unicode_msg, last_position, term); + grub_print_ucs4 (unicode_msg, last_position, 0, 0, term); grub_printf("\n\n"); grub_free (unicode_msg); } diff --git a/normal/menu_text.c b/normal/menu_text.c index 5b75f29fd..61ddd2490 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -38,14 +38,6 @@ struct menu_viewer_data struct grub_term_output *term; }; -static void -print_spaces (int number_spaces, struct grub_term_output *term) -{ - int i; - for (i = 0; i < number_spaces; i++) - grub_putcode (' ', term); -} - grub_ssize_t grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, struct grub_term_output *term) @@ -65,26 +57,11 @@ void grub_print_message_indented (const char *msg, int margin_left, int margin_right, struct grub_term_output *term) { - int line_len; - grub_uint32_t *unicode_msg; grub_uint32_t *last_position; int msg_len; - { - struct grub_unicode_glyph pseudo_glyph = { - .base = ' ', - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; - line_len = grub_term_width (term) - - grub_term_getcharwidth (term, &pseudo_glyph) - * (margin_left + margin_right); - } - msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position); if (msg_len < 0) @@ -92,6 +69,11 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right, return; } + grub_print_ucs4 (unicode_msg, last_position, margin_left, margin_right, term); + +#if 0 + int line_len; + grub_uint32_t *current_position = unicode_msg; grub_uint32_t *next_new_line = unicode_msg; @@ -126,6 +108,7 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right, current_position = next_new_line; first_loop = 0; } +#endif grub_free (unicode_msg); } @@ -280,7 +263,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, } grub_print_ucs4 (unicode_title, - unicode_title + last_printed, term); + unicode_title + last_printed, 0, 0, term); if (last_printed != len) { @@ -397,7 +380,7 @@ menu_text_print_timeout (int timeout, void *dataptr) grub_print_message_indented (msg_translated, 3, 0, data->term); posx = grub_term_getxy (data->term) >> 8; - print_spaces (grub_term_width (data->term) - posx - 1, data->term); + grub_print_spaces (data->term, grub_term_width (data->term) - posx - 1); grub_term_gotoxy (data->term, grub_term_cursor_x (data->term), @@ -455,7 +438,7 @@ menu_text_clear_timeout (void *dataptr) struct menu_viewer_data *data = dataptr; grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3); - print_spaces (grub_term_width (data->term) - 1, data->term); + grub_print_spaces (data->term, grub_term_width (data->term) - 1); grub_term_gotoxy (data->term, grub_term_cursor_x (data->term), GRUB_TERM_FIRST_ENTRY_Y + data->offset); grub_term_refresh (data->term); From 8b4ca088684b625f9dbbf251e2373b77bde4b9e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 14:48:14 +0100 Subject: [PATCH 056/503] better line wrapping --- normal/charset.c | 78 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index 383f2c458..1a9afa4be 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -554,6 +554,8 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, unsigned line_start = 0; grub_ssize_t line_width = startwidth; unsigned k; + grub_ssize_t last_space = -1; + grub_ssize_t last_space_width = 0; auto void revert (unsigned start, unsigned end); void revert (unsigned start, unsigned end) @@ -577,16 +579,29 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, for (k = 0; k <= visual_len; k++) { grub_ssize_t last_width = 0; + if (getcharwidth && k != visual_len) line_width += last_width = getcharwidth (&visual[k]); + + if (k != visual_len && visual[k].base == ' ') + { + last_space = k; + last_space_width = line_width; + } + if (((grub_ssize_t) maxwidth > 0 && line_width > (grub_ssize_t) maxwidth) || k == visual_len) { unsigned min_odd_level = 0xffffffff; unsigned max_level = 0; unsigned j; - unsigned i; + + if (last_space > (signed) line_start) + k = last_space; + else + line_width -= last_width; + for (i = line_start; i < k; i++) { if (levels[i] > max_level) @@ -619,9 +634,12 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, outptr->base = '\n'; outptr++; } - + + if ((signed) k == last_space) + k++; + line_start = k; - line_width = last_width; + line_width -= last_space_width; } } @@ -1102,7 +1120,7 @@ grub_print_ucs4 (const grub_uint32_t * str, int margin_left, int margin_right, struct grub_term_output *term) { - grub_size_t line_len; + grub_ssize_t max_width; grub_ssize_t startwidth; { @@ -1113,7 +1131,7 @@ grub_print_ucs4 (const grub_uint32_t * str, .ncomb = 0, .combining = 0 }; - line_len = grub_term_width (term) + max_width = grub_term_width (term) - grub_term_getcharwidth (term, &space_glyph) * (margin_left + margin_right) - 1; } @@ -1122,6 +1140,7 @@ grub_print_ucs4 (const grub_uint32_t * str, grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff)); startwidth = ((term->getxy () >> 8) & 0xff) - margin_left; + startwidth = 0; if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UCS4_VISUAL @@ -1133,7 +1152,7 @@ grub_print_ucs4 (const grub_uint32_t * str, struct grub_unicode_glyph *visual_ptr; visual_len = grub_bidi_logical_to_visual (str, last_position - str, &visual, term->getcharwidth, - line_len, startwidth); + max_width, startwidth); if (visual_len < 0) { grub_print_error (); @@ -1187,35 +1206,58 @@ grub_print_ucs4 (const grub_uint32_t * str, { const grub_uint32_t *ptr; grub_ssize_t line_width = startwidth; - grub_ssize_t maxwidth = line_len; + grub_ssize_t lastspacewidth = 0; + const grub_uint32_t *line_start = str, *last_space = str - 1; for (ptr = str; ptr < last_position; ptr++) { - struct grub_unicode_glyph c = { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; grub_ssize_t last_width = 0; if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) { + struct grub_unicode_glyph c = { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; c.base = *ptr; line_width += last_width = term->getcharwidth (&c); } - if (line_width > maxwidth || *ptr == '\n') + if (*ptr == ' ') { + lastspacewidth = line_width; + last_space = ptr; + } + + if (line_width > max_width || *ptr == '\n') + { + const grub_uint32_t *ptr2; + + if (line_width > max_width && last_space > line_start) + ptr = last_space; + else + lastspacewidth = line_width - last_width; + + for (ptr2 = line_start; ptr2 < ptr; ptr2++) + grub_putcode (*ptr2, term); + grub_print_spaces (term, margin_right); grub_putcode ('\n', term); grub_putcode ('\r', term); - line_width = last_width; + line_width -= lastspacewidth; grub_print_spaces (term, margin_left); + if (ptr == last_space || *ptr == '\n') + ptr++; + line_start = ptr; } - - if (*ptr != '\n') - grub_putcode (*ptr, term); } + + { + const grub_uint32_t *ptr2; + for (ptr2 = line_start; ptr2 < last_position; ptr2++) + grub_putcode (*ptr2, term); + } } } From 3830c087bb1d384572bbdeb8ba9958f8bc635aac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 15:21:50 +0100 Subject: [PATCH 057/503] Fix few wrapping problems --- normal/charset.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index 1a9afa4be..03e04fc5b 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -597,10 +597,15 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, unsigned j; unsigned i; - if (last_space > (signed) line_start) + if (k != visual_len && last_space > (signed) line_start) k = last_space; + else if (k != visual_len && line_start == 0 && startwidth != 0) + { + k = 0; + last_space_width = startwidth; + } else - line_width -= last_width; + last_space_width = line_width - last_width; for (i = line_start; i < k; i++) { @@ -627,6 +632,8 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, if (is_mirrored (visual[i].base) && levels[i]) visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + grub_memcpy (outptr, &visual[line_start], + (k - line_start) * sizeof (visual[0])); outptr += k - line_start; if (k != visual_len) { @@ -986,6 +993,7 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, grub_memset (visual_ptr, 0, sizeof (visual_ptr[0])); visual_ptr->base = '\n'; visual_ptr++; + line_start++; } } } @@ -1140,7 +1148,6 @@ grub_print_ucs4 (const grub_uint32_t * str, grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff)); startwidth = ((term->getxy () >> 8) & 0xff) - margin_left; - startwidth = 0; if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UCS4_VISUAL @@ -1236,6 +1243,12 @@ grub_print_ucs4 (const grub_uint32_t * str, if (line_width > max_width && last_space > line_start) ptr = last_space; + else if (line_width > max_width + && line_start == str && startwidth != 0) + { + ptr = str; + lastspacewidth = startwidth; + } else lastspacewidth = line_width - last_width; From 7a476ba0a3598839af7300ca3ed289dd4e0fcf1e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 19:04:08 +0100 Subject: [PATCH 058/503] Dedup remapping code --- normal/charset.c | 128 ++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index 03e04fc5b..24413ee76 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1067,11 +1067,10 @@ map_code (grub_uint32_t in, struct grub_term_output *term) return in; } -/* Put a Unicode character. */ -void -grub_putcode (grub_uint32_t code, struct grub_term_output *term) +static void +putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) { - struct grub_unicode_glyph c = + struct grub_unicode_glyph c2 = { .variant = 0, .attributes = 0, @@ -1079,20 +1078,14 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term) .combining = 0 }; - if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE - && ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && (term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_VISUAL)) - return; - - if (code == '\t' && term->getxy) + if (c->base == '\t' && term->getxy) { int n; n = 8 - ((term->getxy () >> 8) & 7); + c2.base = ' '; while (n--) - grub_putcode (' ', term); + (term->putchar) (&c2); return; } @@ -1102,24 +1095,60 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term) || (term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { - grub_uint8_t str[20], *ptr; - - grub_ucs4_to_utf8 (&code, 1, str, sizeof (str)); - - for (ptr = str; *ptr; ptr++) + int i; + for (i = -1; i < (int) c->ncomb; i++) { - c.base = *ptr; - (term->putchar) (&c); + grub_uint8_t u8[20], *ptr; + grub_uint32_t code; + + if (i == -1) + code = c->base; + else + code = c->combining[i].code; + + grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8)); + + for (ptr = u8; *ptr; ptr++) + { + c2.base = *ptr; + (term->putchar) (&c2); + } } } else - { - c.base = map_code (code, term); - (term->putchar) (&c); - } + (term->putchar) (c); - if (code == '\n') - grub_putcode ('\r', term); + if (c->base == '\n') + { + c2.base = '\r'; + (term->putchar) (&c2); + } +} + +static void +putcode_real (grub_uint32_t code, struct grub_term_output *term) +{ + struct grub_unicode_glyph c = + { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + + c.base = map_code (code, term); + putglyph (&c, term); +} + +/* Put a Unicode character. */ +void +grub_putcode (grub_uint32_t code, struct grub_term_output *term) +{ + /* Combining character by itself? */ + if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE) + return; + + putcode_real (code, term); } void @@ -1167,43 +1196,11 @@ grub_print_ucs4 (const grub_uint32_t * str, } for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) { - struct grub_unicode_glyph c = { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; if (visual_ptr->base == '\n') grub_print_spaces (term, margin_right); - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) - { - int i; - for (i = -1; i < (int) visual_ptr->ncomb; i++) - { - grub_uint8_t u8[20], *ptr; - - if (i == -1) - grub_ucs4_to_utf8 (&visual_ptr->base, 1, u8, sizeof (u8)); - else - grub_ucs4_to_utf8 (&visual_ptr->combining[i].code, - 1, u8, sizeof (u8)); - - for (ptr = u8; *ptr; ptr++) - { - c.base = *ptr; - (term->putchar) (&c); - } - } - } - else - term->putchar (visual_ptr); + putglyph (visual_ptr, term); if (visual_ptr->base == '\n') - { - c.base = '\r'; - term->putchar (&c); - grub_print_spaces (term, margin_left); - } + grub_print_spaces (term, margin_left); grub_free (visual_ptr->combining); } grub_free (visual); @@ -1253,11 +1250,18 @@ grub_print_ucs4 (const grub_uint32_t * str, lastspacewidth = line_width - last_width; for (ptr2 = line_start; ptr2 < ptr; ptr2++) - grub_putcode (*ptr2, term); + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } grub_print_spaces (term, margin_right); grub_putcode ('\n', term); - grub_putcode ('\r', term); line_width -= lastspacewidth; grub_print_spaces (term, margin_left); if (ptr == last_space || *ptr == '\n') From d6e0e85bf491e7b87617626330cee428e65982ad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 19:16:15 +0100 Subject: [PATCH 059/503] Disable UTF-8 serial by default --- term/serial.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/term/serial.c b/term/serial.c index 53ba65ac9..18978911f 100644 --- a/term/serial.c +++ b/term/serial.c @@ -49,6 +49,9 @@ static const struct grub_arg_option options[] = {"word", 'w', 0, N_("Set the serial port word length."), 0, ARG_TYPE_INT}, {"parity", 'r', 0, N_("Set the serial port parity."), 0, ARG_TYPE_STRING}, {"stop", 't', 0, N_("Set the serial port stop bits."), 0, ARG_TYPE_INT}, + {"ascii", 'a', 0, N_("Terminal is ASCII-only."), 0, ARG_TYPE_NONE}, + {"utf8", 'l', 0, N_("Terminal is logical-ordered UTF-8."), 0, ARG_TYPE_NONE}, + {"visual-utf8", 'v', 0, N_("Terminal is visually-ordered UTF-8."), 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; @@ -453,7 +456,7 @@ static struct grub_term_output grub_serial_term_output = .cls = grub_serial_cls, .setcolorstate = grub_serial_setcolorstate, .setcursor = grub_serial_setcursor, - .flags = GRUB_TERM_CODE_TYPE_UTF8_VISUAL, + .flags = GRUB_TERM_CODE_TYPE_ASCII, }; @@ -538,6 +541,15 @@ grub_cmd_serial (grub_extcmd_t cmd, } } + grub_serial_term_output.flags &= ~GRUB_TERM_CODE_TYPE_MASK; + + if (state[7].set) + grub_serial_term_output.flags |= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; + else if (state[8].set) + grub_serial_term_output.flags |= GRUB_TERM_CODE_TYPE_UTF8_VISUAL; + else + grub_serial_term_output.flags |= GRUB_TERM_CODE_TYPE_ASCII; + /* Initialize with new settings. */ hwiniterr = serial_hw_init (); From bf17ef45d66d1e14770832c6271bbd60f66e86de Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 19:23:21 +0100 Subject: [PATCH 060/503] Rename UCS4 to glyph description --- include/grub/term.h | 7 ++++--- normal/charset.c | 2 +- term/gfxterm.c | 2 +- term/i386/pc/vga.c | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index d715755cc..573f20331 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -78,9 +78,10 @@ grub_term_color_state; /* UTF-8 stream in logical order. Usually used for terminals which just forward the stream to another computer. */ #define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (1 << 4) -/* UCS-4 in visual order. */ -#define GRUB_TERM_CODE_TYPE_UCS4_VISUAL ((1 << 4) | (1 << 3)) -#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL ((1 << 5) | (1 << 4)) +/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */ +#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL ((1 << 4) | (1 << 3)) +/* Glyph description in visual order. */ +#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (1 << 5) /* Bitmasks for modifier keys returned by grub_getkeystatus. */ diff --git a/normal/charset.c b/normal/charset.c index 24413ee76..53b9578e5 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1179,7 +1179,7 @@ grub_print_ucs4 (const grub_uint32_t * str, startwidth = ((term->getxy () >> 8) & 0xff) - margin_left; if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UCS4_VISUAL + == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS || (term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { diff --git a/term/gfxterm.c b/term/gfxterm.c index 797e714d2..7e35148d4 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -1206,7 +1206,7 @@ static struct grub_term_output grub_video_term = .getcolor = grub_virtual_screen_getcolor, .setcursor = grub_gfxterm_setcursor, .refresh = grub_gfxterm_refresh, - .flags = GRUB_TERM_CODE_TYPE_UCS4_VISUAL, + .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, .next = 0 }; diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c index 448a773ef..036ac592a 100644 --- a/term/i386/pc/vga.c +++ b/term/i386/pc/vga.c @@ -505,7 +505,7 @@ static struct grub_term_output grub_vga_term = .cls = grub_vga_cls, .setcolorstate = grub_vga_setcolorstate, .setcursor = grub_vga_setcursor, - .flags = GRUB_TERM_CODE_TYPE_UCS4_VISUAL, + .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, }; GRUB_MOD_INIT(vga) From 50186d826d63c0298353e8377b2f1a130b454958 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 19:55:09 +0100 Subject: [PATCH 061/503] Fix combining characters messing with width counter --- include/grub/unicode.h | 9 ++++----- kern/term.c | 3 ++- normal/charset.c | 10 ++++++++-- normal/menu_text.c | 3 ++- term/serial.c | 2 +- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/grub/unicode.h b/include/grub/unicode.h index e7f176d0f..2bc9753ed 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -84,6 +84,9 @@ struct grub_unicode_glyph grub_uint32_t code; enum grub_comb_type type; } *combining; + /* Hint by unicode subsystem how wide this character usually is. + Real width is determined by font. Set only in UTF-8 stream. */ + int estimated_width; }; #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 @@ -134,15 +137,11 @@ static inline struct grub_unicode_glyph * grub_unicode_glyph_from_code (grub_uint32_t code) { struct grub_unicode_glyph *ret; - ret = grub_malloc (sizeof (*ret)); + ret = grub_zalloc (sizeof (*ret)); if (!ret) return NULL; ret->base = code; - ret->variant = 0; - ret->attributes = 0; - ret->ncomb = 0; - ret->combining = 0; return ret; } diff --git a/kern/term.c b/kern/term.c index 8139e8118..a65d67196 100644 --- a/kern/term.c +++ b/kern/term.c @@ -41,7 +41,8 @@ grub_putcode_dumb (grub_uint32_t code, .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; if (code == '\t' && term->getxy) diff --git a/normal/charset.c b/normal/charset.c index 53b9578e5..af53b3134 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -538,6 +538,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, out->variant = 0; out->attributes = 0; out->ncomb = 0; + out->estimated_width = 1; out->combining = NULL; } return ptr - in; @@ -1075,7 +1076,8 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; if (c->base == '\t' && term->getxy) @@ -1096,6 +1098,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { int i; + c2.estimated_width = 1; for (i = -1; i < (int) c->ncomb; i++) { grub_uint8_t u8[20], *ptr; @@ -1112,8 +1115,10 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) { c2.base = *ptr; (term->putchar) (&c2); + c2.estimated_width = 0; } } + c2.estimated_width = 1; } else (term->putchar) (c); @@ -1133,7 +1138,8 @@ putcode_real (grub_uint32_t code, struct grub_term_output *term) .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; c.base = map_code (code, term); diff --git a/normal/menu_text.c b/normal/menu_text.c index 61ddd2490..2e2cf0e0c 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -273,7 +273,8 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; x += grub_term_getcharwidth (term, &pseudo_glyph); } diff --git a/term/serial.c b/term/serial.c index 18978911f..666606fcc 100644 --- a/term/serial.c +++ b/term/serial.c @@ -356,7 +356,7 @@ grub_serial_putchar (const struct grub_unicode_glyph *c) serial_hw_put ('\r'); serial_hw_put ('\n'); } - xpos++; + xpos += c->estimated_width; break; } } From 8a0b074f39a2c91003f5e80231a7998fbf24d1b7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 19:56:33 +0100 Subject: [PATCH 062/503] Fix combining characters messing with width counter --- term/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/term/serial.c b/term/serial.c index 666606fcc..b1c5accd1 100644 --- a/term/serial.c +++ b/term/serial.c @@ -348,7 +348,7 @@ grub_serial_putchar (const struct grub_unicode_glyph *c) default: if ((c->base & 0xC0) == 0x80) break; - if (xpos >= TEXT_WIDTH) + if (xpos + c->estimated_width >= TEXT_WIDTH + 1) { xpos = 0; if (ypos < TEXT_HEIGHT - 1) From 2b5af23fa50d1307e20af234c0bf001cfb96dbc8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 20:01:19 +0100 Subject: [PATCH 063/503] Remove leftover --- normal/menu_text.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/normal/menu_text.c b/normal/menu_text.c index 2e2cf0e0c..884eb2c30 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -71,44 +71,6 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right, grub_print_ucs4 (unicode_msg, last_position, margin_left, margin_right, term); -#if 0 - int line_len; - - grub_uint32_t *current_position = unicode_msg; - - grub_uint32_t *next_new_line = unicode_msg; - - int first_loop = 1; - - while (current_position < last_position) - { - if (! first_loop) - grub_putcode ('\n', term); - - next_new_line = (grub_uint32_t *) last_position; - - while (grub_getstringwidth (current_position, next_new_line,term) - > line_len - || (next_new_line != last_position && *next_new_line != ' ' - && next_new_line > current_position)) - { - next_new_line--; - } - - if (next_new_line == current_position) - { - next_new_line = (next_new_line + line_len > last_position) ? - (grub_uint32_t *) last_position : next_new_line + line_len; - } - - print_spaces (margin_left, term); - grub_print_ucs4 (current_position, next_new_line, term); - - next_new_line++; - current_position = next_new_line; - first_loop = 0; - } -#endif grub_free (unicode_msg); } From 6c363dfd54a0abdd6ec8d1a322bbb25a3be80082 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 21:29:15 +0100 Subject: [PATCH 064/503] Fix doublewidth character handling --- Makefile.in | 8 ++++++- conf/common.rmk | 4 ++++ include/grub/term.h | 24 ++++++++++++++++++++ normal/charset.c | 42 +++++++++++++++++++++++++++++++---- term/serial.c | 7 ------ util/grub-mkfont.c | 53 ++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 121 insertions(+), 17 deletions(-) diff --git a/Makefile.in b/Makefile.in index 07fe6219a..dd2fedbf4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -259,7 +259,13 @@ ascii.bitmaps: $(FONT_SOURCE) grub-mkfont ascii.h: ascii.bitmaps grub-bin2h $(builddir)/grub-bin2h ascii_bitmaps < $< > $@ -TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 +widthspec.bin: $(FONT_SOURCE) grub-mkfont + $(builddir)/grub-mkfont --width-spec -o $@ $(FONT_SOURCE) + +widthspec.h: widthspec.bin grub-bin2h + $(builddir)/grub-bin2h widthspec < $< > $@ + +TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1 endif endif diff --git a/conf/common.rmk b/conf/common.rmk index acbb990da..98daa0839 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -640,6 +640,10 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal/menu_entry.c normal/menu_text.c normal/charset.c \ normal/misc.c normal/crypto.c normal/term.c normal/context.c \ unidata.c +ifneq (, $(FONT_SOURCE)) +normal/charset.c_SOURCES += widthspec.h +endif + normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/term.h b/include/grub/term.h index 573f20331..8a9218635 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -380,12 +380,36 @@ grub_term_cls (struct grub_term_output *term) } } +#ifdef HAVE_UNIFONT_WIDTHSPEC + +grub_ssize_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c); + +#else + +static inline grub_ssize_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((unused))) +{ + if (grub_unicode_get_comb_type (c->base)) + return 0; + return 1; +} + +#endif + static inline grub_ssize_t grub_term_getcharwidth (struct grub_term_output *term, const struct grub_unicode_glyph *c) { if (term->getcharwidth) return term->getcharwidth (c); + else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL) + || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) + || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS)) + return grub_unicode_estimate_width (c); else return 1; } diff --git a/normal/charset.c b/normal/charset.c index af53b3134..143836bf2 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -30,6 +30,10 @@ #include #include +#ifdef HAVE_UNIFONT_WIDTHSPEC +#include "widthspec.h" +#endif + grub_ssize_t grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, const grub_uint8_t *src, grub_size_t srcsize, @@ -465,6 +469,21 @@ grub_unicode_get_comb_type (grub_uint32_t c) return GRUB_UNICODE_COMB_NONE; } +#ifdef HAVE_UNIFONT_WIDTHSPEC + +grub_ssize_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c) +{ + if (grub_unicode_get_comb_type (c->base)) + return 0; + if (widthspec[c->base >> 3] & (1 << (c->base & 7))) + return 2; + else + return 1; +} + +#endif + grub_size_t grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, struct grub_unicode_glyph *out) @@ -1098,7 +1117,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { int i; - c2.estimated_width = 1; + c2.estimated_width = grub_term_getcharwidth (term, c); for (i = -1; i < (int) c->ncomb; i++) { grub_uint8_t u8[20], *ptr; @@ -1192,8 +1211,15 @@ grub_print_ucs4 (const grub_uint32_t * str, grub_ssize_t visual_len; struct grub_unicode_glyph *visual; struct grub_unicode_glyph *visual_ptr; + + auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c); + grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c) + { + return grub_term_getcharwidth (term, c); + } + visual_len = grub_bidi_logical_to_visual (str, last_position - str, - &visual, term->getcharwidth, + &visual, getcharwidth, max_width, startwidth); if (visual_len < 0) { @@ -1231,7 +1257,7 @@ grub_print_ucs4 (const grub_uint32_t * str, .combining = 0 }; c.base = *ptr; - line_width += last_width = term->getcharwidth (&c); + line_width += last_width = grub_term_getcharwidth (term, &c); } if (*ptr == ' ') @@ -1279,7 +1305,15 @@ grub_print_ucs4 (const grub_uint32_t * str, { const grub_uint32_t *ptr2; for (ptr2 = line_start; ptr2 < last_position; ptr2++) - grub_putcode (*ptr2, term); + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } } } } diff --git a/term/serial.c b/term/serial.c index b1c5accd1..8b32396ee 100644 --- a/term/serial.c +++ b/term/serial.c @@ -364,12 +364,6 @@ grub_serial_putchar (const struct grub_unicode_glyph *c) serial_hw_put (c->base); } -static grub_ssize_t -grub_serial_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused))) -{ - return 1; -} - static grub_uint16_t grub_serial_getwh (void) { @@ -449,7 +443,6 @@ 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, diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 9d94b687b..c7969011c 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -53,7 +53,8 @@ struct grub_glyph_info enum file_formats { PF2, - ASCII_BITMAPS + ASCII_BITMAPS, + WIDTH_SPEC }; #define GRUB_FONT_FLAG_BOLD 1 @@ -95,6 +96,7 @@ static struct option options[] = {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, {"ascii-bitmaps", no_argument, 0, 0x102}, + {"width-spec", no_argument, 0, 0x103}, {0, 0, 0, 0} }; @@ -111,6 +113,7 @@ Usage: %s [OPTIONS] FONT_FILES\n\ \nOptions:\n\ -o, --output=FILE_NAME set output file name\n\ --ascii-bitmaps save only the ASCII bitmaps\n\ + --width-spec create width summary file\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\ @@ -380,6 +383,32 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file) fclose (file); } +void +write_font_width_spec (struct grub_font_info *font_info, char *output_file) +{ + FILE *file; + struct grub_glyph_info *glyph; + grub_uint8_t *out; + grub_uint8_t *rle; + int rle_size; + int i, j; + + out = xmalloc (8192); + memset (out, 0, 8192); + + file = fopen (output_file, "wb"); + if (! file) + grub_util_error ("Can\'t write to file %s.", output_file); + + for (glyph = font_info->glyph; glyph; glyph = glyph->next) + if (glyph->width > 12) + out[glyph->char_code >> 3] |= (1 << (glyph->char_code & 7)); + + fwrite (out, 8192, 1, file); + fclose (file); + free (out); +} + void write_font_pf2 (struct grub_font_info *font_info, char *output_file) { @@ -648,6 +677,10 @@ main (int argc, char *argv[]) file_format = ASCII_BITMAPS; break; + case 0x103: + file_format = WIDTH_SPEC; + break; + default: usage (1); break; @@ -712,10 +745,20 @@ main (int argc, char *argv[]) FT_Done_FreeType (ft_lib); - if (file_format == PF2) - write_font_pf2 (&font_info, output_file); - else if (file_format == ASCII_BITMAPS) - write_font_ascii_bitmap (&font_info, output_file); + switch (file_format) + { + case PF2: + write_font_pf2 (&font_info, output_file); + break; + + case ASCII_BITMAPS: + write_font_ascii_bitmap (&font_info, output_file); + break; + + case WIDTH_SPEC: + write_font_width_spec (&font_info, output_file); + break; + } if (font_verbosity > 1) print_glyphs (&font_info); From 703cbe63d64e3b5b09afb9357522003585ede4cf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 21:33:23 +0100 Subject: [PATCH 065/503] Remove trivial getcharwidth (now implicit) --- term/efi/console.c | 8 -------- term/i386/pc/console.c | 1 - term/i386/pc/vga_text.c | 1 - term/i386/vga_common.c | 7 ------- term/ieee1275/ofconsole.c | 7 ------- util/console.c | 7 ------- 6 files changed, 31 deletions(-) diff --git a/term/efi/console.c b/term/efi/console.c index 875a23a25..35b265ddb 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -112,13 +112,6 @@ grub_console_putchar (const struct grub_unicode_glyph *c) efi_call_2 (o->output_string, o, str); } -static grub_ssize_t -grub_console_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused))) -{ - /* For now, every printable character has the width 1. */ - return 1; -} - static int grub_console_checkkey (void) { @@ -349,7 +342,6 @@ 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, diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 5def6fca0..146e16643 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -57,7 +57,6 @@ 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, diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index 82cc11967..379eb3579 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -155,7 +155,6 @@ static struct grub_term_output grub_vga_text_term = .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, diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c index 30458b034..f88dbb04e 100644 --- a/term/i386/vga_common.c +++ b/term/i386/vga_common.c @@ -31,13 +31,6 @@ grub_console_putchar (const struct grub_unicode_glyph *c) grub_console_real_putchar (c->base); } -grub_ssize_t -grub_console_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused))) -{ - /* For now, every printable character has the width 1. */ - return 1; -} - grub_uint16_t grub_console_getwh (void) { diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 81e7e7b20..926f5e028 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -107,12 +107,6 @@ grub_ofconsole_putchar (const struct grub_unicode_glyph *c) grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); } -static grub_ssize_t -grub_ofconsole_getcharwidth (const struct grub_unicode_glyph *c __attribute__((unused))) -{ - return 1; -} - static void grub_ofconsole_setcolorstate (grub_term_color_state state) { @@ -449,7 +443,6 @@ static struct grub_term_output grub_ofconsole_term_output = .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, diff --git a/util/console.c b/util/console.c index 91480a810..b4316042e 100644 --- a/util/console.c +++ b/util/console.c @@ -69,12 +69,6 @@ grub_ncurses_putchar (const struct grub_unicode_glyph *c) addch (c->base | grub_console_attr); } -static grub_ssize_t -grub_ncurses_getcharwidth (const struct grub_unicode_glyph * c __attribute__ ((unused))) -{ - return 1; -} - static void grub_ncurses_setcolorstate (grub_term_color_state state) { @@ -317,7 +311,6 @@ static struct grub_term_output grub_ncurses_term_output = .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, From 6f5568ed67eca6d5acd13652f87a399818842921 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 21:57:34 +0100 Subject: [PATCH 066/503] Add mirroring for visual UTF-8 --- autogen.sh | 2 +- include/grub/unicode.h | 7 +++++++ normal/charset.c | 16 +++++++++++++++- util/import_unicode.py | 24 ++++++++++++++++++++++-- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/autogen.sh b/autogen.sh index 5d0b5a282..524b908f5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,7 +13,7 @@ echo timestamp > stamp-h.in python util/import_gcry.py lib/libgcrypt/ . -python util/import_unicode.py util/UnicodeData.txt unidata.c +python util/import_unicode.py util/UnicodeData.txt util/BidiMirroring.txt unidata.c for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do if test -e $rmk ; then diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 2bc9753ed..c96d8854d 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -23,6 +23,12 @@ #include #include +struct grub_unicode_bidi_pair +{ + grub_uint32_t key; + grub_uint32_t replace; +}; + struct grub_unicode_compact_range { grub_uint32_t start:21; @@ -97,6 +103,7 @@ struct grub_unicode_glyph #define GRUB_UNICODE_VARIATION_SELECTOR_256 0xe01ef extern struct grub_unicode_compact_range grub_unicode_compact[]; +extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; #define GRUB_UNICODE_MAX_CACHED_CHAR 0x20000 /* Unicode mandates an arbitrary limit. */ diff --git a/normal/charset.c b/normal/charset.c index 143836bf2..8b81910dc 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1087,6 +1087,16 @@ map_code (grub_uint32_t in, struct grub_term_output *term) return in; } +static grub_uint32_t +mirror_code (grub_uint32_t in) +{ + int i; + for (i = 0; grub_unicode_bidi_pairs[i].key; i++) + if (grub_unicode_bidi_pairs[i].key == in) + return grub_unicode_bidi_pairs[i].replace; + return in; +} + static void putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) { @@ -1124,7 +1134,11 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) grub_uint32_t code; if (i == -1) - code = c->base; + { + code = c->base; + if (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) + code = mirror_code (code); + } else code = c->combining[i].code; diff --git a/util/import_unicode.py b/util/import_unicode.py index e2f0561f0..0fc36c5c2 100644 --- a/util/import_unicode.py +++ b/util/import_unicode.py @@ -25,7 +25,7 @@ if len (sys.argv) < 3: print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) exit (0) infile = open (sys.argv[1], "r") -outfile = open (sys.argv[2], "w") +outfile = open (sys.argv[3], "w") outfile.write ("#include \n") outfile.write ("\n") outfile.write ("struct grub_unicode_compact_range grub_unicode_compact[] = {\n") @@ -69,4 +69,24 @@ if lastbiditype != "L" or lastcombtype != 0 or lastmirrortype: lastmirrortype))) outfile.write ("{0, 0, 0, 0, 0},\n") -outfile.write ("};") +outfile.write ("};\n") + +infile.close () + +infile = open (sys.argv[2], "r") + +outfile.write ("struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[] = {\n") + +for line in infile: + line = re.sub ("#.*$", "", line) + line = line.replace ("\n", "") + line = line.replace (" ", "") + if len (line) == 0 or line[0] == '\n': + continue + sp = line.split (";") + code1 = int (sp[0], 16) + code2 = int (sp[1], 16) + outfile.write ("{0x%x, 0x%x},\n" % (code1, code2)) +outfile.write ("{0, 0},\n") +outfile.write ("};\n") + From bb7f4dbe3ba5ee5169c3e79c617b6c06ff1ea932 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 22:05:50 +0100 Subject: [PATCH 067/503] Explicitly check that terminal is in visual UTF-8 before mirroring code --- normal/charset.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/normal/charset.c b/normal/charset.c index 8b81910dc..452057174 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1136,7 +1136,9 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) if (i == -1) { code = c->base; - if (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL + && (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)) code = mirror_code (code); } else From 701f1df9618e9af81e2b04ae4a109e83c3c9ef8d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 22:34:13 +0100 Subject: [PATCH 068/503] Fix junk newline on second console --- normal/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/normal/main.c b/normal/main.c index ab28609cd..52d9b36fe 100644 --- a/normal/main.c +++ b/normal/main.c @@ -430,7 +430,8 @@ grub_normal_init_page (struct grub_term_output *term) grub_term_gotoxy (term, posx, 1); grub_print_ucs4 (unicode_msg, last_position, 0, 0, term); - grub_printf("\n\n"); + grub_putcode ('\n', term); + grub_putcode ('\n', term); grub_free (unicode_msg); } @@ -550,9 +551,10 @@ grub_normal_reader_init (int nested) { grub_normal_init_page (term); grub_term_setcursor (term, 1); - + grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term); - grub_puts ("\n"); + grub_putcode ('\n', term); + grub_putcode ('\n', term); } grub_free (msg_formatted); From 7c464a1ec55403c08f239aefd3786c45499e1888 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 23:02:48 +0100 Subject: [PATCH 069/503] Don't show gfxmenu error --- normal/menu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/normal/menu.c b/normal/menu.c index 2e722c0a6..e96c99efd 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -246,7 +246,6 @@ menu_init (int entry, grub_menu_t menu, int nested) err = grub_gfxmenu_try_hook (entry, menu, nested); if(!err) continue; - grub_print_error (); grub_errno = GRUB_ERR_NONE; } From eaa1f9a64b83aaa87fae52fe3bbda2457bd1c993 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 23:03:08 +0100 Subject: [PATCH 070/503] Fix few memory errors --- gfxmenu/font.c | 2 +- include/grub/unicode.h | 13 ++++++++----- normal/charset.c | 6 ++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/gfxmenu/font.c b/gfxmenu/font.c index 0c973620a..a11b31875 100644 --- a/gfxmenu/font.c +++ b/gfxmenu/font.c @@ -63,10 +63,10 @@ grub_font_draw_string (const char *str, grub_font_t font, if (!glyph) return grub_errno; err = grub_font_draw_glyph (glyph, color, x, baseline_y); + x += glyph->device_width; grub_free (glyph); if (err) return err; - x += glyph->device_width; } grub_free (visual); diff --git a/include/grub/unicode.h b/include/grub/unicode.h index c96d8854d..b68c7faf5 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -130,13 +130,16 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) if (!out) return NULL; grub_memcpy (out, in, sizeof (*in)); - out->combining = grub_malloc (in->ncomb * sizeof (*in)); - if (!out->combining) + if (in->combining) { - grub_free (out); - return NULL; + out->combining = grub_malloc (in->ncomb * sizeof (*in)); + if (!out->combining) + { + grub_free (out); + return NULL; + } + grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in)); } - grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in)); return out; } diff --git a/normal/charset.c b/normal/charset.c index 452057174..2473f1b52 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -282,7 +282,8 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len, (grub_uint8_t *) msg, -1, 0); - *last_position = *unicode_msg + msg_len; + if (last_position) + *last_position = *unicode_msg + msg_len; return msg_len; } @@ -529,13 +530,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, || comb_type == GRUB_UNICODE_COMB_ME || comb_type == GRUB_UNICODE_COMB_MN) last_comb_pointer = out->ncomb; - n = grub_realloc (out->combining, + n = grub_realloc (out->combining, sizeof (n[0]) * (out->ncomb + 1)); if (!n) { grub_errno = GRUB_ERR_NONE; continue; } + out->combining = n; for (j = last_comb_pointer; j < out->ncomb; j++) if (out->combining[j].type > comb_type) From c2bd1d182e92d1417bdd1a6cb349c4d979a9a5f1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Mar 2010 00:23:23 +0100 Subject: [PATCH 071/503] Fix sporadious newline --- normal/menu_text.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/normal/menu_text.c b/normal/menu_text.c index 884eb2c30..47b7e11f9 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -135,7 +135,7 @@ command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN, (grub_uint32_t) GRUB_TERM_DISP_DOWN); if (!msg_translated) return; - grub_xputs ("\n"); + grub_putcode ('\n', term); grub_print_message_indented (msg_translated, STANDARD_MARGIN, STANDARD_MARGIN, term); From 34fac099a5f48c81669d7363cdb43122046bf366 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Mar 2010 08:37:48 +0100 Subject: [PATCH 072/503] Make grub_console_real_putchar grub_console_putchar --- include/grub/i386/pc/console.h | 1 + include/grub/i386/vga_common.h | 9 --------- kern/i386/pc/startup.S | 7 ++++--- term/i386/pc/vga_text.c | 12 ++++++------ term/i386/vga_common.c | 6 ------ 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index 2a74d152c..b677bb886 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -46,6 +46,7 @@ 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); +void grub_console_putchar (const struct grub_unicode_glyph *c); /* Initialize the console system. */ void grub_console_init (void); diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h index 19f14ebed..7df2b9e9e 100644 --- a/include/grub/i386/vga_common.h +++ b/include/grub/i386/vga_common.h @@ -25,18 +25,9 @@ extern grub_uint8_t grub_console_cur_color; -void -grub_console_putchar (const struct grub_unicode_glyph *c); -grub_ssize_t -grub_console_getcharwidth (const struct grub_unicode_glyph *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/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 23f3f398e..c12dfbb57 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1064,7 +1064,7 @@ xsmap: /* - * void grub_console_real_putchar (int c) + * void grub_console_putchar (const struct grub_unicode_glyph *c) * * Put the character C on the console. Because GRUB wants to write a * character with an attribute, this implementation is a bit tricky. @@ -1077,8 +1077,9 @@ xsmap: * 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 +FUNCTION(grub_console_putchar) + /* Retrieve the base character. */ + movl 0(%eax), %edx pusha movb EXT_C(grub_console_cur_color), %bl diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index 379eb3579..3f352afb4 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -83,10 +83,10 @@ inc_x (void) grub_curr_x++; } -void -grub_console_real_putchar (int c) +static void +grub_vga_text_putchar (const struct grub_unicode_glyph *c) { - switch (c) + switch (c->base) { case '\b': if (grub_curr_x != 0) @@ -99,8 +99,8 @@ grub_console_real_putchar (int c) grub_curr_x = 0; break; default: - screen_write_char (grub_curr_x, - grub_curr_y, c | (grub_console_cur_color << 8)); + screen_write_char (grub_curr_x, grub_curr_y, + c->base | (grub_console_cur_color << 8)); inc_x (); } @@ -154,7 +154,7 @@ 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, + .putchar = grub_vga_text_putchar, .getwh = grub_console_getwh, .getxy = grub_vga_text_getxy, .gotoxy = grub_vga_text_gotoxy, diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c index f88dbb04e..894c5d911 100644 --- a/term/i386/vga_common.c +++ b/term/i386/vga_common.c @@ -25,12 +25,6 @@ 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; -void -grub_console_putchar (const struct grub_unicode_glyph *c) -{ - grub_console_real_putchar (c->base); -} - grub_uint16_t grub_console_getwh (void) { From abe8f24a4757bc7c24ec2f84fab615181b144829 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Mar 2010 08:49:48 +0100 Subject: [PATCH 073/503] Fix widthspec.h dependency --- conf/common.rmk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 98daa0839..d790abade 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -634,15 +634,15 @@ keystatus_mod_CFLAGS = $(COMMON_CFLAGS) keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS) # For normal.mod. +ifneq (, $(FONT_SOURCE)) +normal/charset.c_DEPENDENCIES = widthspec.h +endif normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal/auth.c normal/autofs.c normal/handler.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c normal/charset.c \ normal/misc.c normal/crypto.c normal/term.c normal/context.c \ unidata.c -ifneq (, $(FONT_SOURCE)) -normal/charset.c_SOURCES += widthspec.h -endif normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) From 09f9aa3b2e5df81d73fd803ee2e88c653b3e74ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Mar 2010 08:57:23 +0100 Subject: [PATCH 074/503] Move terminal-related function from normal/charset.c to normal/term.c --- include/grub/unicode.h | 3 + normal/charset.c | 323 +---------------------------------------- normal/term.c | 319 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 321 deletions(-) diff --git a/include/grub/unicode.h b/include/grub/unicode.h index b68c7faf5..249297863 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -156,4 +156,7 @@ grub_unicode_glyph_from_code (grub_uint32_t code) return ret; } +grub_uint32_t +grub_unicode_mirror_code (grub_uint32_t in); + #endif diff --git a/normal/charset.c b/normal/charset.c index 2473f1b52..7c455a357 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1022,75 +1022,8 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, return visual_ptr - *visual_out; } -static grub_uint32_t -map_code (grub_uint32_t in, struct grub_term_output *term) -{ - if (in <= 0x7f) - return in; - - switch (term->flags & GRUB_TERM_CODE_TYPE_MASK) - { - case GRUB_TERM_CODE_TYPE_VGA: - switch (in) - { - case GRUB_TERM_DISP_LEFT: - return 0x1b; - case GRUB_TERM_DISP_UP: - return 0x18; - case GRUB_TERM_DISP_RIGHT: - return 0x1a; - case GRUB_TERM_DISP_DOWN: - return 0x19; - case GRUB_TERM_DISP_HLINE: - return 0xc4; - case GRUB_TERM_DISP_VLINE: - return 0xb3; - case GRUB_TERM_DISP_UL: - return 0xda; - case GRUB_TERM_DISP_UR: - return 0xbf; - case GRUB_TERM_DISP_LL: - return 0xc0; - case GRUB_TERM_DISP_LR: - return 0xd9; - } - return '?'; - case GRUB_TERM_CODE_TYPE_ASCII: - /* Better than nothing. */ - switch (in) - { - case GRUB_TERM_DISP_LEFT: - return '<'; - - case GRUB_TERM_DISP_UP: - return '^'; - - case GRUB_TERM_DISP_RIGHT: - return '>'; - - case GRUB_TERM_DISP_DOWN: - return 'v'; - - case GRUB_TERM_DISP_HLINE: - return '-'; - - case GRUB_TERM_DISP_VLINE: - return '|'; - - case GRUB_TERM_DISP_UL: - case GRUB_TERM_DISP_UR: - case GRUB_TERM_DISP_LL: - case GRUB_TERM_DISP_LR: - return '+'; - - } - return '?'; - } - return in; -} - -static grub_uint32_t -mirror_code (grub_uint32_t in) +grub_uint32_t +grub_unicode_mirror_code (grub_uint32_t in) { int i; for (i = 0; grub_unicode_bidi_pairs[i].key; i++) @@ -1098,255 +1031,3 @@ mirror_code (grub_uint32_t in) return grub_unicode_bidi_pairs[i].replace; return in; } - -static void -putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) -{ - struct grub_unicode_glyph c2 = - { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0, - .estimated_width = 1 - }; - - if (c->base == '\t' && term->getxy) - { - int n; - - n = 8 - ((term->getxy () >> 8) & 7); - c2.base = ' '; - while (n--) - (term->putchar) (&c2); - - return; - } - - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - || (term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) - { - int i; - c2.estimated_width = grub_term_getcharwidth (term, c); - for (i = -1; i < (int) c->ncomb; i++) - { - grub_uint8_t u8[20], *ptr; - grub_uint32_t code; - - if (i == -1) - { - code = c->base; - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL - && (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)) - code = mirror_code (code); - } - else - code = c->combining[i].code; - - grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8)); - - for (ptr = u8; *ptr; ptr++) - { - c2.base = *ptr; - (term->putchar) (&c2); - c2.estimated_width = 0; - } - } - c2.estimated_width = 1; - } - else - (term->putchar) (c); - - if (c->base == '\n') - { - c2.base = '\r'; - (term->putchar) (&c2); - } -} - -static void -putcode_real (grub_uint32_t code, struct grub_term_output *term) -{ - struct grub_unicode_glyph c = - { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0, - .estimated_width = 1 - }; - - c.base = map_code (code, term); - putglyph (&c, term); -} - -/* Put a Unicode character. */ -void -grub_putcode (grub_uint32_t code, struct grub_term_output *term) -{ - /* Combining character by itself? */ - if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE) - return; - - putcode_real (code, term); -} - -void -grub_print_ucs4 (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term) -{ - grub_ssize_t max_width; - grub_ssize_t startwidth; - - { - struct grub_unicode_glyph space_glyph = { - .base = ' ', - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; - max_width = grub_term_width (term) - - grub_term_getcharwidth (term, &space_glyph) - * (margin_left + margin_right) - 1; - } - - if (((term->getxy () >> 8) & 0xff) < margin_left) - grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff)); - - startwidth = ((term->getxy () >> 8) & 0xff) - margin_left; - - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS - || (term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) - { - grub_ssize_t visual_len; - struct grub_unicode_glyph *visual; - struct grub_unicode_glyph *visual_ptr; - - auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c); - grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c) - { - return grub_term_getcharwidth (term, c); - } - - visual_len = grub_bidi_logical_to_visual (str, last_position - str, - &visual, getcharwidth, - max_width, startwidth); - if (visual_len < 0) - { - grub_print_error (); - return; - } - for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) - { - if (visual_ptr->base == '\n') - grub_print_spaces (term, margin_right); - putglyph (visual_ptr, term); - if (visual_ptr->base == '\n') - grub_print_spaces (term, margin_left); - grub_free (visual_ptr->combining); - } - grub_free (visual); - return; - } - - { - const grub_uint32_t *ptr; - grub_ssize_t line_width = startwidth; - grub_ssize_t lastspacewidth = 0; - const grub_uint32_t *line_start = str, *last_space = str - 1; - - for (ptr = str; ptr < last_position; ptr++) - { - grub_ssize_t last_width = 0; - if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) - { - struct grub_unicode_glyph c = { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; - c.base = *ptr; - line_width += last_width = grub_term_getcharwidth (term, &c); - } - - if (*ptr == ' ') - { - lastspacewidth = line_width; - last_space = ptr; - } - - if (line_width > max_width || *ptr == '\n') - { - const grub_uint32_t *ptr2; - - if (line_width > max_width && last_space > line_start) - ptr = last_space; - else if (line_width > max_width - && line_start == str && startwidth != 0) - { - ptr = str; - lastspacewidth = startwidth; - } - else - lastspacewidth = line_width - last_width; - - for (ptr2 = line_start; ptr2 < ptr; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term); - } - - grub_print_spaces (term, margin_right); - grub_putcode ('\n', term); - line_width -= lastspacewidth; - grub_print_spaces (term, margin_left); - if (ptr == last_space || *ptr == '\n') - ptr++; - line_start = ptr; - } - } - - { - const grub_uint32_t *ptr2; - for (ptr2 = line_start; ptr2 < last_position; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term); - } - } - } -} - -void -grub_xputs_normal (const char *str) -{ - grub_term_output_t term; - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - grub_uint32_t *unicode_str, *unicode_last_position; - grub_utf8_to_ucs4_alloc (str, &unicode_str, - &unicode_last_position); - grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); - grub_free (unicode_str); - } -} diff --git a/normal/term.c b/normal/term.c index 8a974d035..a2a313779 100644 --- a/normal/term.c +++ b/normal/term.c @@ -95,6 +95,73 @@ grub_install_newline_hook (void) grub_newline_hook = process_newline; } +static grub_uint32_t +map_code (grub_uint32_t in, struct grub_term_output *term) +{ + if (in <= 0x7f) + return in; + + switch (term->flags & GRUB_TERM_CODE_TYPE_MASK) + { + case GRUB_TERM_CODE_TYPE_VGA: + switch (in) + { + case GRUB_TERM_DISP_LEFT: + return 0x1b; + case GRUB_TERM_DISP_UP: + return 0x18; + case GRUB_TERM_DISP_RIGHT: + return 0x1a; + case GRUB_TERM_DISP_DOWN: + return 0x19; + case GRUB_TERM_DISP_HLINE: + return 0xc4; + case GRUB_TERM_DISP_VLINE: + return 0xb3; + case GRUB_TERM_DISP_UL: + return 0xda; + case GRUB_TERM_DISP_UR: + return 0xbf; + case GRUB_TERM_DISP_LL: + return 0xc0; + case GRUB_TERM_DISP_LR: + return 0xd9; + } + return '?'; + case GRUB_TERM_CODE_TYPE_ASCII: + /* Better than nothing. */ + switch (in) + { + case GRUB_TERM_DISP_LEFT: + return '<'; + + case GRUB_TERM_DISP_UP: + return '^'; + + case GRUB_TERM_DISP_RIGHT: + return '>'; + + case GRUB_TERM_DISP_DOWN: + return 'v'; + + case GRUB_TERM_DISP_HLINE: + return '-'; + + case GRUB_TERM_DISP_VLINE: + return '|'; + + case GRUB_TERM_DISP_UL: + case GRUB_TERM_DISP_UR: + case GRUB_TERM_DISP_LL: + case GRUB_TERM_DISP_LR: + return '+'; + + } + return '?'; + } + return in; +} + void grub_puts_terminal (const char *str, struct grub_term_output *term) { @@ -265,3 +332,255 @@ read_terminal_list (void) grub_errno = GRUB_ERR_NONE; } + +static void +putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) +{ + struct grub_unicode_glyph c2 = + { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0, + .estimated_width = 1 + }; + + if (c->base == '\t' && term->getxy) + { + int n; + + n = 8 - ((term->getxy () >> 8) & 7); + c2.base = ' '; + while (n--) + (term->putchar) (&c2); + + return; + } + + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + || (term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) + { + int i; + c2.estimated_width = grub_term_getcharwidth (term, c); + for (i = -1; i < (int) c->ncomb; i++) + { + grub_uint8_t u8[20], *ptr; + grub_uint32_t code; + + if (i == -1) + { + code = c->base; + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL + && (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)) + code = grub_unicode_mirror_code (code); + } + else + code = c->combining[i].code; + + grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8)); + + for (ptr = u8; *ptr; ptr++) + { + c2.base = *ptr; + (term->putchar) (&c2); + c2.estimated_width = 0; + } + } + c2.estimated_width = 1; + } + else + (term->putchar) (c); + + if (c->base == '\n') + { + c2.base = '\r'; + (term->putchar) (&c2); + } +} + +static void +putcode_real (grub_uint32_t code, struct grub_term_output *term) +{ + struct grub_unicode_glyph c = + { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0, + .estimated_width = 1 + }; + + c.base = map_code (code, term); + putglyph (&c, term); +} + +/* Put a Unicode character. */ +void +grub_putcode (grub_uint32_t code, struct grub_term_output *term) +{ + /* Combining character by itself? */ + if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE) + return; + + putcode_real (code, term); +} + +void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term) +{ + grub_ssize_t max_width; + grub_ssize_t startwidth; + + { + struct grub_unicode_glyph space_glyph = { + .base = ' ', + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + max_width = grub_term_width (term) + - grub_term_getcharwidth (term, &space_glyph) + * (margin_left + margin_right) - 1; + } + + if (((term->getxy () >> 8) & 0xff) < margin_left) + grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff)); + + startwidth = ((term->getxy () >> 8) & 0xff) - margin_left; + + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS + || (term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) + { + grub_ssize_t visual_len; + struct grub_unicode_glyph *visual; + struct grub_unicode_glyph *visual_ptr; + + auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c); + grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c) + { + return grub_term_getcharwidth (term, c); + } + + visual_len = grub_bidi_logical_to_visual (str, last_position - str, + &visual, getcharwidth, + max_width, startwidth); + if (visual_len < 0) + { + grub_print_error (); + return; + } + for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) + { + if (visual_ptr->base == '\n') + grub_print_spaces (term, margin_right); + putglyph (visual_ptr, term); + if (visual_ptr->base == '\n') + grub_print_spaces (term, margin_left); + grub_free (visual_ptr->combining); + } + grub_free (visual); + return; + } + + { + const grub_uint32_t *ptr; + grub_ssize_t line_width = startwidth; + grub_ssize_t lastspacewidth = 0; + const grub_uint32_t *line_start = str, *last_space = str - 1; + + for (ptr = str; ptr < last_position; ptr++) + { + grub_ssize_t last_width = 0; + if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) + { + struct grub_unicode_glyph c = { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + c.base = *ptr; + line_width += last_width = grub_term_getcharwidth (term, &c); + } + + if (*ptr == ' ') + { + lastspacewidth = line_width; + last_space = ptr; + } + + if (line_width > max_width || *ptr == '\n') + { + const grub_uint32_t *ptr2; + + if (line_width > max_width && last_space > line_start) + ptr = last_space; + else if (line_width > max_width + && line_start == str && startwidth != 0) + { + ptr = str; + lastspacewidth = startwidth; + } + else + lastspacewidth = line_width - last_width; + + for (ptr2 = line_start; ptr2 < ptr; ptr2++) + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } + + grub_print_spaces (term, margin_right); + grub_putcode ('\n', term); + line_width -= lastspacewidth; + grub_print_spaces (term, margin_left); + if (ptr == last_space || *ptr == '\n') + ptr++; + line_start = ptr; + } + } + + { + const grub_uint32_t *ptr2; + for (ptr2 = line_start; ptr2 < last_position; ptr2++) + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } + } + } +} + +void +grub_xputs_normal (const char *str) +{ + grub_term_output_t term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + grub_uint32_t *unicode_str, *unicode_last_position; + grub_utf8_to_ucs4_alloc (str, &unicode_str, + &unicode_last_position); + grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); + grub_free (unicode_str); + } +} From ce04e79272a9d782bdd69c59dfa61508357fd02d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 16:02:06 +0100 Subject: [PATCH 075/503] Remove leftover variables --- util/grub-mkfont.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index c7969011c..49c5095ac 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -389,9 +389,6 @@ write_font_width_spec (struct grub_font_info *font_info, char *output_file) FILE *file; struct grub_glyph_info *glyph; grub_uint8_t *out; - grub_uint8_t *rle; - int rle_size; - int i, j; out = xmalloc (8192); memset (out, 0, 8192); From 81b0623a6c86e314b50041f0648f76f6f168add6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 16:28:35 +0100 Subject: [PATCH 076/503] Make few more points bidi-clean --- normal/menu_entry.c | 6 +++--- normal/term.c | 23 +++++++++-------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 74887b8ab..be2d18fc9 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -1094,10 +1094,10 @@ complete (struct screen *screen, int continuous, int update) else grub_putcode (' ', screen->terms[i].term); - while (*p && p < endp) - grub_putcode (*p++, screen->terms[i].term); + grub_print_ucs4 (p, ucs4 + ucs4len < endp ? ucs4 + ucs4len : endp, + 0, 0, screen->terms[i].term); - if (*p) + if (ucs4 + ucs4len > endp) grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term); grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF); } diff --git a/normal/term.c b/normal/term.c index a2a313779..9488f68bc 100644 --- a/normal/term.c +++ b/normal/term.c @@ -165,17 +165,12 @@ map_code (grub_uint32_t in, struct grub_term_output *term) void grub_puts_terminal (const char *str, struct grub_term_output *term) { - grub_uint32_t code; - grub_ssize_t ret; - const grub_uint8_t *ptr = (const grub_uint8_t *) str; - const grub_uint8_t *end; - end = (const grub_uint8_t *) (str + grub_strlen (str)); + grub_uint32_t *unicode_str, *unicode_last_position; + grub_utf8_to_ucs4_alloc (str, &unicode_str, + &unicode_last_position); - while (*ptr) - { - ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr); - grub_putcode (code, term); - } + grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); + grub_free (unicode_str); } grub_uint16_t * @@ -574,13 +569,13 @@ void grub_xputs_normal (const char *str) { grub_term_output_t term; + grub_uint32_t *unicode_str, *unicode_last_position; + grub_utf8_to_ucs4_alloc (str, &unicode_str, + &unicode_last_position); FOR_ACTIVE_TERM_OUTPUTS(term) { - grub_uint32_t *unicode_str, *unicode_last_position; - grub_utf8_to_ucs4_alloc (str, &unicode_str, - &unicode_last_position); grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); - grub_free (unicode_str); } + grub_free (unicode_str); } From 36b71abfaa4de0f1f4e75085c64c5a7ddf8a4d93 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 16:46:45 +0100 Subject: [PATCH 077/503] Fix few memory bugs --- normal/menu_entry.c | 162 +++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 77 deletions(-) diff --git a/normal/menu_entry.c b/normal/menu_entry.c index be2d18fc9..20d602597 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -243,6 +243,9 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, { int column; + if (linep >= screen->lines + screen->num_lines) + break; + for (column = 0; column <= linep->len && y < grub_term_num_entries (term_screen->term); @@ -337,7 +340,7 @@ insert_string (struct screen *screen, char *s, int update) screen->num_lines++; screen->lines = grub_realloc (screen->lines, screen->num_lines - * sizeof (struct line)); + * sizeof (screen->lines[0])); if (! screen->lines) return 0; @@ -1020,87 +1023,92 @@ complete (struct screen *screen, int continuous, int update) insert = grub_normal_do_completion (linep->buf, &restore, store_completion); linep->buf[screen->column] = saved_char; - - buflen = grub_strlen (completion_buffer.buf); - ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1)); - - if (!ucs4) + + if (completion_buffer.buf) { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - return 1; - } + buflen = grub_strlen (completion_buffer.buf); + ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1)); + + if (!ucs4) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + return 1; + } - ucs4len = grub_utf8_to_ucs4 (ucs4, buflen, - (grub_uint8_t *) completion_buffer.buf, - buflen, 0); - ucs4[ucs4len] = 0; + ucs4len = grub_utf8_to_ucs4 (ucs4, buflen, + (grub_uint8_t *) completion_buffer.buf, + buflen, 0); + ucs4[ucs4len] = 0; - if (restore) - for (i = 0; i < screen->nterms; i++) - { - int num_sections = ((completion_buffer.len - + grub_term_width (screen->terms[i].term) - 8 - 1) - / (grub_term_width (screen->terms[i].term) - 8)); - grub_uint32_t *endp; - grub_uint16_t pos; - grub_uint32_t *p = ucs4; - - pos = grub_term_getxy (screen->terms[i].term); - grub_term_gotoxy (screen->terms[i].term, 0, - grub_term_height (screen->terms[i].term) - 3); - - screen->completion_shown = 1; - - grub_term_gotoxy (screen->terms[i].term, 0, - grub_term_height (screen->terms[i].term) - 3); - grub_puts_terminal (" ", screen->terms[i].term); - switch (completion_type) + if (restore) + for (i = 0; i < screen->nterms; i++) { - case GRUB_COMPLETION_TYPE_COMMAND: - grub_puts_terminal (_("Possible commands are:"), - screen->terms[i].term); - break; - case GRUB_COMPLETION_TYPE_DEVICE: - grub_puts_terminal (_("Possible devices are:"), - screen->terms[i].term); - break; - case GRUB_COMPLETION_TYPE_FILE: - grub_puts_terminal (_("Possible files are:"), - screen->terms[i].term); - break; - case GRUB_COMPLETION_TYPE_PARTITION: - grub_puts_terminal (_("Possible partitions are:"), - screen->terms[i].term); - break; - case GRUB_COMPLETION_TYPE_ARGUMENT: - grub_puts_terminal (_("Possible arguments are:"), - screen->terms[i].term); - break; - default: - grub_puts_terminal (_("Possible things are:"), - screen->terms[i].term); - break; + int num_sections = ((completion_buffer.len + + grub_term_width (screen->terms[i].term) + - 8 - 1) + / (grub_term_width (screen->terms[i].term) + - 8)); + grub_uint32_t *endp; + grub_uint16_t pos; + grub_uint32_t *p = ucs4; + + pos = grub_term_getxy (screen->terms[i].term); + grub_term_gotoxy (screen->terms[i].term, 0, + grub_term_height (screen->terms[i].term) - 3); + + screen->completion_shown = 1; + + grub_term_gotoxy (screen->terms[i].term, 0, + grub_term_height (screen->terms[i].term) - 3); + grub_puts_terminal (" ", screen->terms[i].term); + switch (completion_type) + { + case GRUB_COMPLETION_TYPE_COMMAND: + grub_puts_terminal (_("Possible commands are:"), + screen->terms[i].term); + break; + case GRUB_COMPLETION_TYPE_DEVICE: + grub_puts_terminal (_("Possible devices are:"), + screen->terms[i].term); + break; + case GRUB_COMPLETION_TYPE_FILE: + grub_puts_terminal (_("Possible files are:"), + screen->terms[i].term); + break; + case GRUB_COMPLETION_TYPE_PARTITION: + grub_puts_terminal (_("Possible partitions are:"), + screen->terms[i].term); + break; + case GRUB_COMPLETION_TYPE_ARGUMENT: + grub_puts_terminal (_("Possible arguments are:"), + screen->terms[i].term); + break; + default: + grub_puts_terminal (_("Possible things are:"), + screen->terms[i].term); + break; + } + + grub_puts_terminal ("\n ", screen->terms[i].term); + + p += (count % num_sections) + * (grub_term_width (screen->terms[i].term) - 8); + endp = p + (grub_term_width (screen->terms[i].term) - 8); + + if (p != ucs4) + grub_putcode (GRUB_TERM_DISP_LEFT, screen->terms[i].term); + else + grub_putcode (' ', screen->terms[i].term); + + grub_print_ucs4 (p, ucs4 + ucs4len < endp ? ucs4 + ucs4len : endp, + 0, 0, screen->terms[i].term); + + if (ucs4 + ucs4len > endp) + grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term); + grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF); } - - grub_puts_terminal ("\n ", screen->terms[i].term); - - p += (count % num_sections) - * (grub_term_width (screen->terms[i].term) - 8); - endp = p + (grub_term_width (screen->terms[i].term) - 8); - - if (p != ucs4) - grub_putcode (GRUB_TERM_DISP_LEFT, screen->terms[i].term); - else - grub_putcode (' ', screen->terms[i].term); - - grub_print_ucs4 (p, ucs4 + ucs4len < endp ? ucs4 + ucs4len : endp, - 0, 0, screen->terms[i].term); - - if (ucs4 + ucs4len > endp) - grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term); - grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF); - } + } if (insert) { From 6fcebedeeda11d284a35ca231e7cce95be9e6d49 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 16:51:53 +0100 Subject: [PATCH 078/503] Replace line counter with char counter --- include/grub/normal.h | 2 +- normal/menu.c | 4 ++-- normal/term.c | 18 +++++++++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/grub/normal.h b/include/grub/normal.h index 6ec14d31a..a5352cdcf 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -112,7 +112,7 @@ void read_terminal_list (void); void grub_set_more (int onoff); -int grub_normal_get_line_counter (void); +int grub_normal_get_char_counter (void); void grub_install_newline_hook (void); void grub_xputs_normal (const char *str); diff --git a/normal/menu.c b/normal/menu.c index e96c99efd..60311970f 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -558,13 +558,13 @@ show_menu (grub_menu_t menu, int nested) } else { - int lines_before = grub_normal_get_line_counter (); + int chars_before = grub_normal_get_char_counter (); grub_errno = GRUB_ERR_NONE; grub_menu_execute_entry (e); grub_print_error (); grub_errno = GRUB_ERR_NONE; - if (lines_before != grub_normal_get_line_counter ()) + if (chars_before != grub_normal_get_char_counter ()) grub_wait_after_message (); } } diff --git a/normal/term.c b/normal/term.c index 9488f68bc..493127b65 100644 --- a/normal/term.c +++ b/normal/term.c @@ -25,18 +25,26 @@ #include #include +struct term_state +{ + struct term_state *next; + struct grub_unicode_glyph *backlog; + int numlines; + char *term_name; +}; + /* The amount of lines counted by the pager. */ static unsigned grub_more_lines; /* If the more pager is active. */ static int grub_more; -static int grub_normal_line_counter = 0; +static int grub_normal_char_counter = 0; int -grub_normal_get_line_counter (void) +grub_normal_get_char_counter (void) { - return grub_normal_line_counter; + return grub_normal_char_counter; } static void @@ -50,8 +58,6 @@ process_newline (void) height = grub_term_height (cur); grub_more_lines++; - grub_normal_line_counter++; - if (grub_more && grub_more_lines >= height - 1) { char key; @@ -340,6 +346,8 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) .estimated_width = 1 }; + grub_normal_char_counter++; + if (c->base == '\t' && term->getxy) { int n; From 3c69fb81e14cfa6d222b32185bf227532185a990 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 17:54:31 +0100 Subject: [PATCH 079/503] Restore and enhance pager functionality --- include/grub/normal.h | 1 - normal/main.c | 1 - normal/term.c | 465 ++++++++++++++++++++++++++++-------------- 3 files changed, 316 insertions(+), 151 deletions(-) diff --git a/include/grub/normal.h b/include/grub/normal.h index a5352cdcf..dbc2be327 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -113,7 +113,6 @@ void read_terminal_list (void); void grub_set_more (int onoff); int grub_normal_get_char_counter (void); -void grub_install_newline_hook (void); void grub_xputs_normal (const char *str); diff --git a/normal/main.c b/normal/main.c index 52d9b36fe..9e4d5eb30 100644 --- a/normal/main.c +++ b/normal/main.c @@ -661,7 +661,6 @@ GRUB_MOD_INIT(normal) grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); - grub_install_newline_hook (); grub_register_variable_hook ("pager", 0, grub_env_write_pager); /* Register a command "normal" for the rescue mode. */ diff --git a/normal/term.c b/normal/term.c index 493127b65..a8a3e63de 100644 --- a/normal/term.c +++ b/normal/term.c @@ -28,11 +28,17 @@ struct term_state { struct term_state *next; - struct grub_unicode_glyph *backlog; - int numlines; + const struct grub_unicode_glyph *backlog_glyphs; + const grub_uint32_t *backlog_ucs4; + grub_size_t backlog_len; + + void *free; + int num_lines; char *term_name; }; +static struct term_state *term_states = NULL; + /* The amount of lines counted by the pager. */ static unsigned grub_more_lines; @@ -48,40 +54,52 @@ grub_normal_get_char_counter (void) } static void -process_newline (void) +print_more (void) { - struct grub_term_output *cur; - unsigned height = -1; + char key; + grub_uint16_t *pos; + grub_term_output_t term; + grub_uint32_t *unicode_str, *unicode_last_position; - FOR_ACTIVE_TERM_OUTPUTS(cur) - if (grub_term_height (cur) < height) - height = grub_term_height (cur); - grub_more_lines++; + pos = grub_term_save_pos (); - if (grub_more && grub_more_lines >= height - 1) + grub_utf8_to_ucs4_alloc ("--MORE--", &unicode_str, + &unicode_last_position); + + if (!unicode_str) { - char key; - grub_uint16_t *pos; - - pos = grub_term_save_pos (); - - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("--MORE--"); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - - key = grub_getkey (); - - /* Remove the message. */ - grub_term_restore_pos (pos); - grub_printf (" "); - grub_term_restore_pos (pos); - - /* Scroll one lines or an entire page, depending on the key. */ - if (key == '\r' || key =='\n') - grub_more_lines = height - 2; - else - grub_more_lines = 0; + grub_errno = GRUB_ERR_NONE; + return; } + + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); + } + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + + grub_free (unicode_str); + + key = grub_getkey (); + + /* Remove the message. */ + grub_term_restore_pos (pos); + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_print_spaces (term, 8); + grub_term_restore_pos (pos); + + /* Scroll one lines or an entire page, depending on the key. */ + + { + static struct term_state *state; + for (state = term_states; state; state = state->next) + if (key == '\r' || key =='\n') + state->num_lines = 0; + else + state->num_lines -= 2; + } } void @@ -95,12 +113,6 @@ grub_set_more (int onoff) grub_more_lines = 0; } -void -grub_install_newline_hook (void) -{ - grub_newline_hook = process_newline; -} - static grub_uint32_t map_code (grub_uint32_t in, struct grub_term_output *term) { @@ -431,33 +443,230 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term) putcode_real (code, term); } -void -grub_print_ucs4 (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term) +static grub_ssize_t +get_maxwidth (struct grub_term_output *term, + int margin_left, int margin_right) { - grub_ssize_t max_width; - grub_ssize_t startwidth; + struct grub_unicode_glyph space_glyph = { + .base = ' ', + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + return (grub_term_width (term) + - grub_term_getcharwidth (term, &space_glyph) + * (margin_left + margin_right) - 1); +} + +static grub_ssize_t +get_startwidth (struct grub_term_output *term, + int margin_left) +{ + return ((term->getxy () >> 8) & 0xff) - margin_left; +} + +static int +print_ucs4_terminal (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term, + struct term_state *state) +{ + const grub_uint32_t *ptr; + grub_ssize_t startwidth = get_startwidth (term, margin_left); + grub_ssize_t line_width = startwidth; + grub_ssize_t lastspacewidth = 0; + grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right); + const grub_uint32_t *line_start = str, *last_space = str - 1; + + for (ptr = str; ptr < last_position; ptr++) + { + grub_ssize_t last_width = 0; + if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) + { + struct grub_unicode_glyph c = { + .variant = 0, + .attributes = 0, + .ncomb = 0, + .combining = 0 + }; + c.base = *ptr; + line_width += last_width = grub_term_getcharwidth (term, &c); + } + + if (*ptr == ' ') + { + lastspacewidth = line_width; + last_space = ptr; + } + + if (line_width > max_width || *ptr == '\n') + { + const grub_uint32_t *ptr2; + + if (line_width > max_width && last_space > line_start) + ptr = last_space; + else if (line_width > max_width + && line_start == str && startwidth != 0) + { + ptr = str; + lastspacewidth = startwidth; + } + else + lastspacewidth = line_width - last_width; + + for (ptr2 = line_start; ptr2 < ptr; ptr2++) + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } + + grub_print_spaces (term, margin_right); + grub_putcode ('\n', term); + if (state && state->num_lines++ + >= (grub_ssize_t) grub_term_height (term)) + { + state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') + ? ptr + 1 : ptr; + state->backlog_len = last_position - state->backlog_ucs4; + return 1; + } + + line_width -= lastspacewidth; + grub_print_spaces (term, margin_left); + if (ptr == last_space || *ptr == '\n') + ptr++; + line_start = ptr; + } + } { - struct grub_unicode_glyph space_glyph = { - .base = ' ', - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; - max_width = grub_term_width (term) - - grub_term_getcharwidth (term, &space_glyph) - * (margin_left + margin_right) - 1; + const grub_uint32_t *ptr2; + for (ptr2 = line_start; ptr2 < last_position; ptr2++) + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } } + return 0; +} + +static struct term_state * +find_term_state (struct grub_term_output *term) +{ + struct term_state *state; + for (state = term_states; state; state = state->next) + if (grub_strcmp (state->term_name, term->name) == 0) + return state; + + state = grub_zalloc (sizeof (*state)); + if (!state) + { + grub_errno = GRUB_ERR_NONE; + return NULL; + } + + state->term_name = grub_strdup (term->name); + state->next = term_states; + term_states = state; + + return state; +} + +static int +put_glyphs_terminal (const struct grub_unicode_glyph *visual, + grub_ssize_t visual_len, + int margin_left, int margin_right, + struct grub_term_output *term, + struct term_state *state) +{ + const struct grub_unicode_glyph *visual_ptr; + for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) + { + if (visual_ptr->base == '\n') + grub_print_spaces (term, margin_right); + putglyph (visual_ptr, term); + if (state && state->num_lines++ >= (grub_ssize_t) grub_term_height (term)) + { + state->backlog_glyphs = visual_ptr + 1; + state->backlog_len = visual_len - (visual - visual_ptr) - 1; + return 1; + } + + if (visual_ptr->base == '\n') + grub_print_spaces (term, margin_left); + grub_free (visual_ptr->combining); + } + return 0; +} + +static int +print_backlog (struct grub_term_output *term, + int margin_left, int margin_right) +{ + struct term_state *state = find_term_state (term); + + if (!state) + return 0; + + if (state->backlog_ucs4) + { + int ret; + ret = print_ucs4_terminal (state->backlog_ucs4, + state->backlog_ucs4 + state->backlog_len, + margin_left, margin_right, term, state); + if (!ret) + { + grub_free (state->free); + state->free = NULL; + state->backlog_len = 0; + } + return ret; + } + + if (state->backlog_glyphs) + { + int ret; + ret = put_glyphs_terminal (state->backlog_glyphs, + state->backlog_len, + margin_left, margin_right, term, state); + if (!ret) + { + grub_free (state->free); + state->free = NULL; + state->backlog_len = 0; + } + return ret; + } + + return 0; +} + +static int +print_ucs4_real (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term, int backlog) +{ + struct term_state *state = NULL; + + if (backlog) + state = find_term_state (term); if (((term->getxy () >> 8) & 0xff) < margin_left) grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff)); - startwidth = ((term->getxy () >> 8) & 0xff) - margin_left; - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS || (term->flags & GRUB_TERM_CODE_TYPE_MASK) @@ -465,7 +674,7 @@ grub_print_ucs4 (const grub_uint32_t * str, { grub_ssize_t visual_len; struct grub_unicode_glyph *visual; - struct grub_unicode_glyph *visual_ptr; + int ret; auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c); grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c) @@ -475,115 +684,73 @@ grub_print_ucs4 (const grub_uint32_t * str, visual_len = grub_bidi_logical_to_visual (str, last_position - str, &visual, getcharwidth, - max_width, startwidth); + get_maxwidth (term, + margin_left, + margin_right), + get_startwidth (term, + margin_left)); if (visual_len < 0) { grub_print_error (); - return; + return 0; } - for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) - { - if (visual_ptr->base == '\n') - grub_print_spaces (term, margin_right); - putglyph (visual_ptr, term); - if (visual_ptr->base == '\n') - grub_print_spaces (term, margin_left); - grub_free (visual_ptr->combining); - } - grub_free (visual); - return; + ret = put_glyphs_terminal (visual, visual_len, margin_left, margin_right, + term, state); + if (!ret) + grub_free (visual); + else + state->free = visual; + return ret; } - - { - const grub_uint32_t *ptr; - grub_ssize_t line_width = startwidth; - grub_ssize_t lastspacewidth = 0; - const grub_uint32_t *line_start = str, *last_space = str - 1; - - for (ptr = str; ptr < last_position; ptr++) - { - grub_ssize_t last_width = 0; - if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) - { - struct grub_unicode_glyph c = { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; - c.base = *ptr; - line_width += last_width = grub_term_getcharwidth (term, &c); - } - - if (*ptr == ' ') - { - lastspacewidth = line_width; - last_space = ptr; - } - - if (line_width > max_width || *ptr == '\n') - { - const grub_uint32_t *ptr2; - - if (line_width > max_width && last_space > line_start) - ptr = last_space; - else if (line_width > max_width - && line_start == str && startwidth != 0) - { - ptr = str; - lastspacewidth = startwidth; - } - else - lastspacewidth = line_width - last_width; - - for (ptr2 = line_start; ptr2 < ptr; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term); - } - - grub_print_spaces (term, margin_right); - grub_putcode ('\n', term); - line_width -= lastspacewidth; - grub_print_spaces (term, margin_left); - if (ptr == last_space || *ptr == '\n') - ptr++; - line_start = ptr; - } - } - - { - const grub_uint32_t *ptr2; - for (ptr2 = line_start; ptr2 < last_position; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term); - } - } - } + return print_ucs4_terminal (str, last_position, margin_left, margin_right, + term, state); } +void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term) +{ + print_ucs4_real (str, last_position, margin_left, margin_right, + term, 0); +} + + void grub_xputs_normal (const char *str) { grub_term_output_t term; grub_uint32_t *unicode_str, *unicode_last_position; + int backlog = 0; grub_utf8_to_ucs4_alloc (str, &unicode_str, &unicode_last_position); + if (!unicode_str) + { + grub_errno = GRUB_ERR_NONE; + return; + } + FOR_ACTIVE_TERM_OUTPUTS(term) { - grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); + int cur; + cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0, + term, 1); + if (cur) + backlog = 1; } + while (backlog) + { + print_more (); + backlog = 0; + FOR_ACTIVE_TERM_OUTPUTS(term) + { + int cur; + cur = print_backlog (term, 0, 0); + if (cur) + backlog = 1; + } + } grub_free (unicode_str); } From 5c56cac95f5597ebfb598db9c974b0525233a265 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 18:06:49 +0100 Subject: [PATCH 080/503] Fix few pager bugs --- include/grub/normal.h | 1 + normal/cmdline.c | 3 +++ normal/term.c | 37 +++++++++++++++++++++---------------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/grub/normal.h b/include/grub/normal.h index dbc2be327..ca5bd759a 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -113,6 +113,7 @@ void read_terminal_list (void); void grub_set_more (int onoff); int grub_normal_get_char_counter (void); +void grub_normal_reset_more (void); void grub_xputs_normal (const char *str); diff --git a/normal/cmdline.c b/normal/cmdline.c index f10dc47fe..daa0a1adb 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -362,6 +362,7 @@ grub_cmdline_get (const char *prompt) grub_putcode ('\n', term); } grub_printf ("%s ", prompt_translated); + grub_normal_reset_more (); { struct cmdline_term *cl_term_cur; @@ -440,6 +441,8 @@ grub_cmdline_get (const char *prompt) print_completion); grub_free (bufu8); + grub_normal_reset_more (); + if (restore) { /* Restore the prompt. */ diff --git a/normal/term.c b/normal/term.c index a8a3e63de..09299f647 100644 --- a/normal/term.c +++ b/normal/term.c @@ -39,9 +39,6 @@ struct term_state static struct term_state *term_states = NULL; -/* The amount of lines counted by the pager. */ -static unsigned grub_more_lines; - /* If the more pager is active. */ static int grub_more; @@ -53,6 +50,14 @@ grub_normal_get_char_counter (void) return grub_normal_char_counter; } +void +grub_normal_reset_more (void) +{ + static struct term_state *state; + for (state = term_states; state; state = state->next) + state->num_lines = 0; +} + static void print_more (void) { @@ -92,14 +97,14 @@ print_more (void) /* Scroll one lines or an entire page, depending on the key. */ - { - static struct term_state *state; - for (state = term_states; state; state = state->next) - if (key == '\r' || key =='\n') - state->num_lines = 0; - else + if (key == '\r' || key =='\n') + grub_normal_reset_more (); + else + { + static struct term_state *state; + for (state = term_states; state; state = state->next) state->num_lines -= 2; - } + } } void @@ -109,8 +114,7 @@ grub_set_more (int onoff) grub_more++; else grub_more--; - - grub_more_lines = 0; + grub_normal_reset_more (); } static grub_uint32_t @@ -529,8 +533,8 @@ print_ucs4_terminal (const grub_uint32_t * str, grub_print_spaces (term, margin_right); grub_putcode ('\n', term); - if (state && state->num_lines++ - >= (grub_ssize_t) grub_term_height (term)) + if (state && ++state->num_lines + >= (grub_ssize_t) grub_term_height (term) - 2) { state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') ? ptr + 1 : ptr; @@ -597,7 +601,8 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual, if (visual_ptr->base == '\n') grub_print_spaces (term, margin_right); putglyph (visual_ptr, term); - if (state && state->num_lines++ >= (grub_ssize_t) grub_term_height (term)) + if (state && ++state->num_lines + >= (grub_ssize_t) grub_term_height (term) - 2) { state->backlog_glyphs = visual_ptr + 1; state->backlog_len = visual_len - (visual - visual_ptr) - 1; @@ -736,7 +741,7 @@ grub_xputs_normal (const char *str) { int cur; cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0, - term, 1); + term, grub_more); if (cur) backlog = 1; } From 1f22d20c8cbfc9bd9dd4d24d675a13d2aceea045 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 18:17:54 +0100 Subject: [PATCH 081/503] Fix yeeloong compilation --- commands/videotest.c | 1 + gfxmenu/font.c | 1 + include/grub/font.h | 8 -------- include/grub/gfxmenu_view.h | 8 ++++++++ 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/commands/videotest.c b/commands/videotest.c index 390811a71..77a63a322 100644 --- a/commands/videotest.c +++ b/commands/videotest.c @@ -25,6 +25,7 @@ #include #include #include +#include static grub_err_t grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), diff --git a/gfxmenu/font.c b/gfxmenu/font.c index a11b31875..3c15e19fa 100644 --- a/gfxmenu/font.c +++ b/gfxmenu/font.c @@ -29,6 +29,7 @@ #include #include #include +#include /* 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, diff --git a/include/grub/font.h b/include/grub/font.h index 4df4c2279..b896159c2 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -100,9 +100,6 @@ int EXPORT_FUNC (grub_font_get_height) (grub_font_t font); int EXPORT_FUNC (grub_font_get_xheight) (grub_font_t font); -int EXPORT_FUNC (grub_font_get_string_width) (grub_font_t font, - const char *str); - struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph) (grub_font_t font, grub_uint32_t code); @@ -113,11 +110,6 @@ grub_err_t EXPORT_FUNC (grub_font_draw_glyph) (struct grub_font_glyph *glyph, grub_video_color_t color, int left_x, int baseline_y); -grub_err_t EXPORT_FUNC (grub_font_draw_string) (const char *str, - grub_font_t font, - grub_video_color_t color, - int left_x, int baseline_y); - int EXPORT_FUNC (grub_font_get_constructed_device_width) (grub_font_t hinted_font, const struct grub_unicode_glyph *glyph_id); diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h index 7cbfa89d3..c52a3c71c 100644 --- a/include/grub/gfxmenu_view.h +++ b/include/grub/gfxmenu_view.h @@ -62,6 +62,14 @@ grub_gfxmenu_print_timeout (int timeout, void *data); void grub_gfxmenu_set_chosen_entry (int entry, void *data); +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 grub_font_get_string_width (grub_font_t font, + const char *str); + + /* Implementation details -- this should not be used outside of the view itself. */ From 45511ee976feb5016dc32bed47748696896a6259 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 18:39:02 +0100 Subject: [PATCH 082/503] below right support --- font/font.c | 11 +++++++++++ include/grub/unicode.h | 1 + 2 files changed, 12 insertions(+) diff --git a/font/font.c b/font/font.c index 6209b60d2..5b573b852 100644 --- a/font/font.c +++ b/font/font.c @@ -1122,6 +1122,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, struct grub_video_signed_rect bounds; unsigned i; signed above_rightx, above_righty; + signed below_rightx, below_righty; auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, signed dx, signed dy); void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, @@ -1176,6 +1177,9 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, above_rightx = bounds.x + bounds.width; above_righty = bounds.y + bounds.height; + below_rightx = bounds.x + bounds.width; + below_righty = bounds.y; + for (i = 0; i < glyph_id->ncomb; i++) { grub_int16_t space = 0; @@ -1210,6 +1214,13 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, minimal_device_width (above_rightx); break; + case GRUB_UNICODE_COMB_BELOW_RIGHT: + do_blit (combining_glyphs[i], below_rightx, + below_righty); + below_rightx += combining_glyphs[i]->width; + minimal_device_width (below_rightx); + break; + case GRUB_UNICODE_STACK_ABOVE: space = combining_glyphs[i]->offset_y - grub_font_get_xheight (combining_glyphs[i]->font); diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 249297863..ac8911827 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -69,6 +69,7 @@ enum grub_comb_type GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, GRUB_UNICODE_STACK_BELOW = 220, + GRUB_UNICODE_COMB_BELOW_RIGHT = 222, GRUB_UNICODE_STACK_ABOVE = 230, GRUB_UNICODE_COMB_ABOVE_RIGHT = 232, GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240, From 7624beba471049c85d5f05094a4555a724022616 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 19:13:46 +0100 Subject: [PATCH 083/503] Above left support. Various fixups --- font/font.c | 41 ++++++++++++++++++++++++++--------------- include/grub/unicode.h | 1 + 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/font/font.c b/font/font.c index 5b573b852..992871c1e 100644 --- a/font/font.c +++ b/font/font.c @@ -1122,7 +1122,9 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, struct grub_video_signed_rect bounds; unsigned i; signed above_rightx, above_righty; + signed above_leftx, above_lefty; signed below_rightx, below_righty; + signed min_devwidth = 0; auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, signed dx, signed dy); void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, @@ -1147,14 +1149,6 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, bounds.height = src->height + (-src->height - dy) - bounds.y; } - auto void minimal_device_width (int val); - void minimal_device_width (int val) - { - if (glyph && glyph->device_width < val) - glyph->device_width = val; - if (device_width && *device_width < val) - *device_width = val; - } auto void add_device_width (int val); void add_device_width (int val) { @@ -1174,9 +1168,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, bounds.width = main_glyph->width; bounds.height = main_glyph->height; - above_rightx = bounds.x + bounds.width; + above_rightx = main_glyph->offset_x + main_glyph->width; above_righty = bounds.y + bounds.height; + above_leftx = main_glyph->offset_x; + above_lefty = bounds.y + bounds.height; + below_rightx = bounds.x + bounds.width; below_righty = bounds.y; @@ -1198,27 +1195,31 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, centerx, (bounds.height - combining_glyphs[i]->height) / 2 -(bounds.height + bounds.y)); - minimal_device_width (combining_glyphs[i]->width); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; break; case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT: do_blit (combining_glyphs[i], above_rightx, -above_righty); above_rightx += combining_glyphs[i]->width; - minimal_device_width (above_rightx); break; case GRUB_UNICODE_COMB_ABOVE_RIGHT: do_blit (combining_glyphs[i], above_rightx, -(above_righty + combining_glyphs[i]->height)); above_rightx += combining_glyphs[i]->width; - minimal_device_width (above_rightx); + break; + + case GRUB_UNICODE_COMB_ABOVE_LEFT: + above_leftx -= combining_glyphs[i]->width; + do_blit (combining_glyphs[i], above_leftx, + -(above_lefty + combining_glyphs[i]->height)); break; case GRUB_UNICODE_COMB_BELOW_RIGHT: do_blit (combining_glyphs[i], below_rightx, below_righty); below_rightx += combining_glyphs[i]->width; - minimal_device_width (below_rightx); break; case GRUB_UNICODE_STACK_ABOVE: @@ -1231,7 +1232,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, do_blit (combining_glyphs[i], centerx, -(bounds.height + bounds.y + space + combining_glyphs[i]->height)); - minimal_device_width (combining_glyphs[i]->width); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; break; /* I don't know how ypogegrammeni differs from subscript. */ @@ -1245,7 +1247,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, case GRUB_UNICODE_STACK_ATTACHED_BELOW: do_blit (combining_glyphs[i], centerx, -(bounds.y - space)); - minimal_device_width (combining_glyphs[i]->width); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; break; default: @@ -1263,6 +1266,14 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, } } } + add_device_width ((above_rightx > below_rightx ? above_rightx : below_rightx) + - (main_glyph->offset_x + main_glyph->width)); + add_device_width (above_leftx - main_glyph->offset_x); + if (glyph && glyph->device_width < min_devwidth) + glyph->device_width = min_devwidth; + if (device_width && *device_width < min_devwidth) + *device_width = min_devwidth; + if (bounds_out) *bounds_out = bounds; } diff --git a/include/grub/unicode.h b/include/grub/unicode.h index ac8911827..4e40d4648 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -70,6 +70,7 @@ enum grub_comb_type GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, GRUB_UNICODE_STACK_BELOW = 220, GRUB_UNICODE_COMB_BELOW_RIGHT = 222, + GRUB_UNICODE_COMB_ABOVE_LEFT = 228, GRUB_UNICODE_STACK_ABOVE = 230, GRUB_UNICODE_COMB_ABOVE_RIGHT = 232, GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240, From 832d13705c41a399130e90f85de007eb2c009577 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 21:50:27 +0100 Subject: [PATCH 084/503] Most hebrew diacritics support (except dagesh and final kaf rules) --- font/font.c | 52 +++++++++++++++++++++++++++++++++++++----- include/grub/unicode.h | 18 +++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/font/font.c b/font/font.c index 992871c1e..1fc10aa91 100644 --- a/font/font.c +++ b/font/font.c @@ -1180,7 +1180,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, for (i = 0; i < glyph_id->ncomb; i++) { grub_int16_t space = 0; - grub_int16_t centerx = (bounds.width - combining_glyphs[i]->width) / 2 + /* Center by default. */ + grub_int16_t targetx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x; if (!combining_glyphs[i]) @@ -1192,7 +1193,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, { case GRUB_UNICODE_COMB_OVERLAY: do_blit (combining_glyphs[i], - centerx, + targetx, (bounds.height - combining_glyphs[i]->height) / 2 -(bounds.height + bounds.y)); if (min_devwidth < combining_glyphs[i]->width) @@ -1222,20 +1223,59 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, below_rightx += combining_glyphs[i]->width; break; + case GRUB_UNICODE_COMB_HEBREW_HOLAM: + if (glyph_id->base != GRUB_UNICODE_HEBREW_WAW) + targetx = main_glyph->offset_x - combining_glyphs[i]->width - (combining_glyphs[i]->width + 3) / 4; + goto above_on_main; + + case GRUB_UNICODE_COMB_HEBREW_SIN_DOT: + targetx = main_glyph->offset_x + combining_glyphs[i]->width / 4; + goto above_on_main; + + case GRUB_UNICODE_COMB_HEBREW_SHIN_DOT: + targetx = main_glyph->width + main_glyph->offset_x - combining_glyphs[i]->width; + above_on_main: + space = combining_glyphs[i]->offset_y + - grub_font_get_xheight (combining_glyphs[i]->font) - 1; + if (space <= 0) + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + do_blit (combining_glyphs[i], targetx, + -(main_glyph->height + main_glyph->offset_y + space + + combining_glyphs[i]->height)); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_HEBREW_RAFE: case GRUB_UNICODE_STACK_ABOVE: space = combining_glyphs[i]->offset_y - - grub_font_get_xheight (combining_glyphs[i]->font); - if (space < 0) + - grub_font_get_xheight (combining_glyphs[i]->font) - 1; + if (space <= 0) space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; case GRUB_UNICODE_STACK_ATTACHED_ABOVE: - do_blit (combining_glyphs[i], centerx, + do_blit (combining_glyphs[i], targetx, -(bounds.height + bounds.y + space + combining_glyphs[i]->height)); if (min_devwidth < combining_glyphs[i]->width) min_devwidth = combining_glyphs[i]->width; break; + case GRUB_UNICODE_COMB_HEBREW_SHEVA: + case GRUB_UNICODE_COMB_HEBREW_HIRIQ: + case GRUB_UNICODE_COMB_HEBREW_QAMATS: + case GRUB_UNICODE_COMB_HEBREW_TSERE: + case GRUB_UNICODE_COMB_HEBREW_SEGOL: + /* , + GRUB_UNICODE_COMB_HEBREW_DAGESH = 21*/ + /* TODO: placement in final kaf and under reish. */ + + case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL: + case GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH: + case GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS: + case GRUB_UNICODE_COMB_HEBREW_PATAH: + case GRUB_UNICODE_COMB_HEBREW_QUBUTS: + case GRUB_UNICODE_COMB_HEBREW_METEG: /* I don't know how ypogegrammeni differs from subscript. */ case GRUB_UNICODE_COMB_YPOGEGRAMMENI: case GRUB_UNICODE_STACK_BELOW: @@ -1245,7 +1285,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; case GRUB_UNICODE_STACK_ATTACHED_BELOW: - do_blit (combining_glyphs[i], centerx, + do_blit (combining_glyphs[i], targetx, -(bounds.y - space)); if (min_devwidth < combining_glyphs[i]->width) min_devwidth = combining_glyphs[i]->width; diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 4e40d4648..457bcd93b 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -65,6 +65,23 @@ enum grub_comb_type { GRUB_UNICODE_COMB_NONE = 0, GRUB_UNICODE_COMB_OVERLAY = 1, + GRUB_UNICODE_COMB_HEBREW_SHEVA = 10, + GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL = 11, + GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH = 12, + GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS = 13, + GRUB_UNICODE_COMB_HEBREW_HIRIQ = 14, + GRUB_UNICODE_COMB_HEBREW_TSERE = 15, + GRUB_UNICODE_COMB_HEBREW_SEGOL = 16, + GRUB_UNICODE_COMB_HEBREW_PATAH = 17, + GRUB_UNICODE_COMB_HEBREW_QAMATS = 18, + GRUB_UNICODE_COMB_HEBREW_HOLAM = 19, + GRUB_UNICODE_COMB_HEBREW_QUBUTS = 20, + GRUB_UNICODE_COMB_HEBREW_DAGESH = 21, + GRUB_UNICODE_COMB_HEBREW_METEG = 22, + GRUB_UNICODE_COMB_HEBREW_RAFE = 23, + GRUB_UNICODE_COMB_HEBREW_SHIN_DOT = 24, + GRUB_UNICODE_COMB_HEBREW_SIN_DOT = 25, + GRUB_UNICODE_COMB_HEBREW_VARIKA = 26, GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, @@ -103,6 +120,7 @@ struct grub_unicode_glyph #define GRUB_UNICODE_VARIATION_SELECTOR_16 0xfe0f #define GRUB_UNICODE_VARIATION_SELECTOR_17 0xe0100 #define GRUB_UNICODE_VARIATION_SELECTOR_256 0xe01ef +#define GRUB_UNICODE_HEBREW_WAW 0x05d5 extern struct grub_unicode_compact_range grub_unicode_compact[]; extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; From 521bf3018f6e8927c451824fa08a041b169c6cf9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 23:19:27 +0100 Subject: [PATCH 085/503] Add character properties checking and a comment about problematic characters --- normal/charset.c | 19 +++++++++++++++++++ util/import_unicode.py | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/normal/charset.c b/normal/charset.c index 7c455a357..00bbcb815 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -16,6 +16,25 @@ * along with GRUB. If not, see . */ +/* + Current problems with Unicode rendering: + - B and BN bidi type characters (ignored) + - Mc type characters with combining class 0 (treated as non-combining) + - Mn type characters with combining class 0 (treated as non-combining) + - Me type characters with combining class 0 (treated as non-combining) + - Cf type characters (ignored) + - Cc type characters (ignored) + - Line-breaking rules (e.g. Zs type characters) + - Indic languages + - Arabic shaping + - Zl and Zp characters + - Combining characters of types 7, 8, 9, 21, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 84, 91, 103, 107, 118, 122, 129, 130, 132, + 218, 224, 226, 233, 234 + - Private use surrogates + - Private use characters (not really a problem) + */ + /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string. Return the number of characters converted. DEST must be able to hold diff --git a/util/import_unicode.py b/util/import_unicode.py index 0fc36c5c2..e0e53b655 100644 --- a/util/import_unicode.py +++ b/util/import_unicode.py @@ -45,12 +45,35 @@ for line in infile: print ("UnicodeData.txt uses combination type %d. Conflict." \ % curcombtype) raise + if sp[2] != "Lu" and sp[2] != "Ll" and sp[2] != "Lt" and sp[2] != "Lm" \ + and sp[2] != "Lo"\ + and sp[2] != "Me" and sp[2] != "Mc" and sp[2] != "Mn" \ + and sp[2] != "Nd" and sp[2] != "Nl" and sp[2] != "No" \ + and sp[2] != "Pc" and sp[2] != "Pd" and sp[2] != "Ps" \ + and sp[2] != "Pe" and sp[2] != "Pi" and sp[2] != "Pf" \ + and sp[2] != "Po" \ + and sp[2] != "Sm" and sp[2] != "Sc" and sp[2] != "Sk" \ + and sp[2] != "So"\ + and sp[2] != "Zs" and sp[2] != "Zl" and sp[2] != "Zp" \ + and sp[2] != "Cc" and sp[2] != "Cf" and sp[2] != "Cs" \ + and sp[2] != "Co": + print ("WARNING: Unknown type %s" % sp[2]) if curcombtype == 0 and sp[2] == "Me": curcombtype = 253 if curcombtype == 0 and sp[2] == "Mc": curcombtype = 254 if curcombtype == 0 and sp[2] == "Mn": curcombtype = 255 + if (curcombtype >= 2 and curcombtype <= 6) \ + or (curcombtype >= 37 and curcombtype != 84 and curcombtype != 91 and curcombtype != 103 and curcombtype != 107 and curcombtype != 118 and curcombtype != 122 and curcombtype != 129 and curcombtype != 130 and curcombtype != 132 and curcombtype != 202 and \ + curcombtype != 214 and curcombtype != 216 and \ + curcombtype != 218 and curcombtype != 220 and \ + curcombtype != 222 and curcombtype != 224 and curcombtype != 226 and curcombtype != 228 and \ + curcombtype != 230 and curcombtype != 232 and curcombtype != 233 and \ + curcombtype != 234 and \ + curcombtype != 240 and curcombtype != 253 and \ + curcombtype != 254 and curcombtype != 255): + print ("WARNING: Unknown combining type %d" % curcombtype) if lastcode + 1 != curcode or curbiditype != lastbiditype \ or curcombtype != lastcombtype or curmirrortype != lastmirrortype: if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0 or \ From 6fd346ea6c74028c7b9d8ab554ecc9898b2eff06 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 23:20:35 +0100 Subject: [PATCH 086/503] Update UnicodeData.txt --- util/UnicodeData.txt | 3377 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 2935 insertions(+), 442 deletions(-) diff --git a/util/UnicodeData.txt b/util/UnicodeData.txt index 77db788cf..6b01d90a7 100644 --- a/util/UnicodeData.txt +++ b/util/UnicodeData.txt @@ -169,7 +169,7 @@ 00A8;DIAERESIS;Sk;0;ON; 0020 0308;;;;N;SPACING DIAERESIS;;;; 00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;; 00AA;FEMININE ORDINAL INDICATOR;Ll;0;L; 0061;;;;N;;;;; -00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;*;;; +00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;; 00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;; 00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;; 00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;; @@ -185,7 +185,7 @@ 00B8;CEDILLA;Sk;0;ON; 0020 0327;;;;N;SPACING CEDILLA;;;; 00B9;SUPERSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;; 00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L; 006F;;;;N;;;;; -00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;*;;; +00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;; 00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;; 00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;; 00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;; @@ -196,7 +196,7 @@ 00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3; 00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4; 00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5; -00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;ash *;;00E6; +00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6; 00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7; 00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8; 00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9; @@ -206,7 +206,7 @@ 00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED; 00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE; 00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF; -00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;Icelandic;;00F0; +00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0; 00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1; 00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2; 00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3; @@ -220,15 +220,15 @@ 00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB; 00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC; 00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD; -00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;Icelandic;;00FE; -00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;German;;; +00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE; +00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;; 00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0 00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1 00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2 00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3 00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4 00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5 -00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;ash *;00C6;;00C6 +00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6 00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7 00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8 00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9 @@ -238,7 +238,7 @@ 00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD 00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE 00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF -00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;Icelandic;00D0;;00D0 +00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0 00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1 00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2 00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3 @@ -252,7 +252,7 @@ 00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB 00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC 00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD -00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;Icelandic;00DE;;00DE +00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;;00DE;;00DE 00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178 0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101; 0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100 @@ -310,7 +310,7 @@ 0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134 0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137; 0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136 -0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;Greenlandic;;; +0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;;;; 0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A; 013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139 013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C; @@ -328,8 +328,8 @@ 0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148; 0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147 0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L; 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;; -014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;Sami;;014B; -014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;Sami;014A;;014A +014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;014B; +014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;;014A;;014A 014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D; 014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C 014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F; @@ -348,12 +348,12 @@ 015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A 015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D; 015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C -015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;*;;015F; -015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;*;015E;;015E +015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;;;015F; +015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;;015E;;015E 0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161; 0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160 -0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;*;;0163; -0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;*;0162;;0162 +0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;;;0163; +0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;;0162;;0162 0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165; 0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164 0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167; @@ -391,7 +391,7 @@ 0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254; 0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188; 0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187 -0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;*;;0256; +0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;;;0256; 018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257; 018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C; 018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B @@ -403,7 +403,7 @@ 0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191 0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260; 0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263; -0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;hwair;01F6;;01F6 +0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;;01F6;;01F6 0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269; 0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268; 0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199; @@ -413,14 +413,14 @@ 019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F; 019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272; 019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220 -019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;*;;0275; +019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;;;0275; 01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1; 01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0 -01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;gha;;01A3; -01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;gha;01A2;;01A2 +01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;;;01A3; +01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;;01A2;;01A2 01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5; 01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4 -01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;*;;0280; +01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;;;0280; 01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8; 01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7 01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283; @@ -480,8 +480,8 @@ 01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE 01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1; 01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0 -01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;ash *;;01E3; -01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;ash *;01E2;;01E2 +01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3; +01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2 01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5; 01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4 01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7; @@ -506,8 +506,8 @@ 01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8 01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB; 01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA -01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;ash *;;01FD; -01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;ash *;01FC;;01FC +01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;;;01FD; +01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;;01FC;;01FC 01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF; 01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE 0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201; @@ -534,10 +534,10 @@ 0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214 0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217; 0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216 -0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;*;;0219; -0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;*;0218;;0218 -021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;*;;021B; -021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;*;021A;;021A +0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;;;0219; +0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;;0218;;0218 +021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;;;021B; +021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;;021A;;021A 021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D; 021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C 021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F; @@ -573,8 +573,8 @@ 023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B 023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A; 023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66; -023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;;; -0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;;; +023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7E;;2C7E +0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7F;;2C7F 0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242; 0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241 0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180; @@ -592,7 +592,7 @@ 024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E 0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F 0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D -0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;;; +0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;2C70;;2C70 0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181 0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186 0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;; @@ -638,7 +638,7 @@ 027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64 027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;; 027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; -0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;*;01A6;;01A6 +0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6 0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; 0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;; 0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 @@ -709,11 +709,11 @@ 02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; 02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; 02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;; -02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;Mandarin Chinese third tone;;; +02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;;;; 02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;; -02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;Mandarin Chinese first tone;;; -02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;Mandarin Chinese second tone;;; -02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;Mandarin Chinese fourth tone;;; +02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;;;; +02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;;;; +02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;;;; 02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;; 02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;; 02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;; @@ -727,7 +727,7 @@ 02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;; 02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;; 02D8;BREVE;Sk;0;ON; 0020 0306;;;;N;SPACING BREVE;;;; -02D9;DOT ABOVE;Sk;0;ON; 0020 0307;;;;N;SPACING DOT ABOVE;Mandarin Chinese light tone;;; +02D9;DOT ABOVE;Sk;0;ON; 0020 0307;;;;N;SPACING DOT ABOVE;;;; 02DA;RING ABOVE;Sk;0;ON; 0020 030A;;;;N;SPACING RING ABOVE;;;; 02DB;OGONEK;Sk;0;ON; 0020 0328;;;;N;SPACING OGONEK;;;; 02DC;SMALL TILDE;Sk;0;ON; 0020 0303;;;;N;SPACING TILDE;;;; @@ -766,15 +766,15 @@ 02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;; 02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;; 02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;; -0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;Varia;;; -0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;Oxia, Tonos;;; +0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;;;; +0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;;;; 0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;; 0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;; 0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;; 0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;; -0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;Vrachy;;; +0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;;;; 0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;; -0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;Dialytika;;; +0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;;;; 0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;; 030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;; 030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;; @@ -785,8 +785,8 @@ 0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;; 0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;; 0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;; -0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;Psili;;; -0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;Dasia;;; +0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;;;; +0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;;;; 0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;; 0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;; 0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;; @@ -830,8 +830,8 @@ 033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;; 033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;; 033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;; -0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;Vietnamese;;; -0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;Vietnamese;;; +0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;;;; +0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;;;; 0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;; 0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;; 0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;; @@ -882,15 +882,15 @@ 0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370 0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373; 0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372 -0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;Dexia keraia;;; -0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;Aristeri keraia;;; +0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;;;; +0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;;;; 0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377; 0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376 037A;GREEK YPOGEGRAMMENI;Lm;0;L; 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;; 037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD 037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE 037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF -037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;Erotimatiko;;; +037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;;;; 0384;GREEK TONOS;Sk;0;ON; 0020 0301;;;;N;GREEK SPACING TONOS;;;; 0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;; 0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC; @@ -972,8 +972,8 @@ 03D5;GREEK PHI SYMBOL;Ll;0;L; 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6 03D6;GREEK PI SYMBOL;Ll;0;L; 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0 03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF -03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;*;;03D9; -03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;*;03D8;;03D8 +03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;;;03D9; +03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;;03D8;;03D8 03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB; 03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA 03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD; @@ -1014,19 +1014,19 @@ 03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D; 0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450; 0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451; -0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;Serbocroatian;;0452; +0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;;;0452; 0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453; 0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454; 0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455; 0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456; -0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;Ukrainian;;0457; +0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;;;0457; 0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458; 0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459; 040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A; -040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;Serbocroatian;;045B; +040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;;;045B; 040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C; 040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D; -040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;Byelorussian;;045E; +040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;;;045E; 040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F; 0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430; 0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431; @@ -1094,19 +1094,19 @@ 044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F 0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400 0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401 -0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;Serbocroatian;0402;;0402 +0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;;0402;;0402 0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403 0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404 0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405 0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406 -0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;Ukrainian;0407;;0407 +0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;;0407;;0407 0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408 0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409 045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A -045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;Serbocroatian;040B;;040B +045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;;040B;;040B 045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C 045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D -045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;Byelorussian;040E;;040E +045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;;040E;;040E 045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F 0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461; 0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460 @@ -1178,8 +1178,8 @@ 04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2 04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5; 04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4 -04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;Abkhasian;;04A7; -04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;Abkhasian;04A6;;04A6 +04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;;;04A7; +04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;;04A6;;04A6 04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9; 04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8 04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB; @@ -1192,8 +1192,8 @@ 04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0 04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3; 04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2 -04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;Abkhasian;;04B5; -04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;Abkhasian;04B4;;04B4 +04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;;;04B5; +04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;;04B4;;04B4 04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7; 04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6 04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9; @@ -1304,6 +1304,8 @@ 0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520 0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523; 0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522 +0524;CYRILLIC CAPITAL LETTER PE WITH DESCENDER;Lu;0;L;;;;;N;;;;0525; +0525;CYRILLIC SMALL LETTER PE WITH DESCENDER;Ll;0;L;;;;;N;;;0524;;0524 0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561; 0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562; 0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563; @@ -1395,9 +1397,9 @@ 0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;; 0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;; 0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;; -0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;*;;; +0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;;;; 0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;; -0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;*;;; +0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;;;; 0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;; 059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;; 059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;; @@ -1410,12 +1412,12 @@ 05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;; 05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;; 05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;; -05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;*;;; +05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;;;; 05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;; 05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;; -05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;*;;; +05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;;;; 05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;; -05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;*;;; +05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;;;; 05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;; 05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;; 05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;; @@ -1433,14 +1435,14 @@ 05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;; 05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;; 05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;; -05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;or shuruq;;; -05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;*;;; +05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;;;; +05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;;;; 05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;; 05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;; -05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;*;;; +05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;;;; 05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;; 05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;; -05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;*;;; +05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;;;; 05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;; 05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;; 05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;; @@ -1646,7 +1648,7 @@ 06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;; 06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;; 06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;; -06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;*;;; +06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;;;; 06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;; 06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;; 06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; @@ -1679,7 +1681,7 @@ 06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;; 06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;; 06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; -06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;*;;; +06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;;;; 06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;; 06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;; 06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;; @@ -1961,6 +1963,68 @@ 07F8;NKO COMMA;Po;0;ON;;;;;N;;;;; 07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; 07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;; +0800;SAMARITAN LETTER ALAF;Lo;0;R;;;;;N;;;;; +0801;SAMARITAN LETTER BIT;Lo;0;R;;;;;N;;;;; +0802;SAMARITAN LETTER GAMAN;Lo;0;R;;;;;N;;;;; +0803;SAMARITAN LETTER DALAT;Lo;0;R;;;;;N;;;;; +0804;SAMARITAN LETTER IY;Lo;0;R;;;;;N;;;;; +0805;SAMARITAN LETTER BAA;Lo;0;R;;;;;N;;;;; +0806;SAMARITAN LETTER ZEN;Lo;0;R;;;;;N;;;;; +0807;SAMARITAN LETTER IT;Lo;0;R;;;;;N;;;;; +0808;SAMARITAN LETTER TIT;Lo;0;R;;;;;N;;;;; +0809;SAMARITAN LETTER YUT;Lo;0;R;;;;;N;;;;; +080A;SAMARITAN LETTER KAAF;Lo;0;R;;;;;N;;;;; +080B;SAMARITAN LETTER LABAT;Lo;0;R;;;;;N;;;;; +080C;SAMARITAN LETTER MIM;Lo;0;R;;;;;N;;;;; +080D;SAMARITAN LETTER NUN;Lo;0;R;;;;;N;;;;; +080E;SAMARITAN LETTER SINGAAT;Lo;0;R;;;;;N;;;;; +080F;SAMARITAN LETTER IN;Lo;0;R;;;;;N;;;;; +0810;SAMARITAN LETTER FI;Lo;0;R;;;;;N;;;;; +0811;SAMARITAN LETTER TSAADIY;Lo;0;R;;;;;N;;;;; +0812;SAMARITAN LETTER QUF;Lo;0;R;;;;;N;;;;; +0813;SAMARITAN LETTER RISH;Lo;0;R;;;;;N;;;;; +0814;SAMARITAN LETTER SHAN;Lo;0;R;;;;;N;;;;; +0815;SAMARITAN LETTER TAAF;Lo;0;R;;;;;N;;;;; +0816;SAMARITAN MARK IN;Mn;230;NSM;;;;;N;;;;; +0817;SAMARITAN MARK IN-ALAF;Mn;230;NSM;;;;;N;;;;; +0818;SAMARITAN MARK OCCLUSION;Mn;230;NSM;;;;;N;;;;; +0819;SAMARITAN MARK DAGESH;Mn;230;NSM;;;;;N;;;;; +081A;SAMARITAN MODIFIER LETTER EPENTHETIC YUT;Lm;0;R;;;;;N;;;;; +081B;SAMARITAN MARK EPENTHETIC YUT;Mn;230;NSM;;;;;N;;;;; +081C;SAMARITAN VOWEL SIGN LONG E;Mn;230;NSM;;;;;N;;;;; +081D;SAMARITAN VOWEL SIGN E;Mn;230;NSM;;;;;N;;;;; +081E;SAMARITAN VOWEL SIGN OVERLONG AA;Mn;230;NSM;;;;;N;;;;; +081F;SAMARITAN VOWEL SIGN LONG AA;Mn;230;NSM;;;;;N;;;;; +0820;SAMARITAN VOWEL SIGN AA;Mn;230;NSM;;;;;N;;;;; +0821;SAMARITAN VOWEL SIGN OVERLONG A;Mn;230;NSM;;;;;N;;;;; +0822;SAMARITAN VOWEL SIGN LONG A;Mn;230;NSM;;;;;N;;;;; +0823;SAMARITAN VOWEL SIGN A;Mn;230;NSM;;;;;N;;;;; +0824;SAMARITAN MODIFIER LETTER SHORT A;Lm;0;R;;;;;N;;;;; +0825;SAMARITAN VOWEL SIGN SHORT A;Mn;230;NSM;;;;;N;;;;; +0826;SAMARITAN VOWEL SIGN LONG U;Mn;230;NSM;;;;;N;;;;; +0827;SAMARITAN VOWEL SIGN U;Mn;230;NSM;;;;;N;;;;; +0828;SAMARITAN MODIFIER LETTER I;Lm;0;R;;;;;N;;;;; +0829;SAMARITAN VOWEL SIGN LONG I;Mn;230;NSM;;;;;N;;;;; +082A;SAMARITAN VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;; +082B;SAMARITAN VOWEL SIGN O;Mn;230;NSM;;;;;N;;;;; +082C;SAMARITAN VOWEL SIGN SUKUN;Mn;230;NSM;;;;;N;;;;; +082D;SAMARITAN MARK NEQUDAA;Mn;230;NSM;;;;;N;;;;; +0830;SAMARITAN PUNCTUATION NEQUDAA;Po;0;R;;;;;N;;;;; +0831;SAMARITAN PUNCTUATION AFSAAQ;Po;0;R;;;;;N;;;;; +0832;SAMARITAN PUNCTUATION ANGED;Po;0;R;;;;;N;;;;; +0833;SAMARITAN PUNCTUATION BAU;Po;0;R;;;;;N;;;;; +0834;SAMARITAN PUNCTUATION ATMAAU;Po;0;R;;;;;N;;;;; +0835;SAMARITAN PUNCTUATION SHIYYAALAA;Po;0;R;;;;;N;;;;; +0836;SAMARITAN ABBREVIATION MARK;Po;0;R;;;;;N;;;;; +0837;SAMARITAN PUNCTUATION MELODIC QITSA;Po;0;R;;;;;N;;;;; +0838;SAMARITAN PUNCTUATION ZIQAA;Po;0;R;;;;;N;;;;; +0839;SAMARITAN PUNCTUATION QITSA;Po;0;R;;;;;N;;;;; +083A;SAMARITAN PUNCTUATION ZAEF;Po;0;R;;;;;N;;;;; +083B;SAMARITAN PUNCTUATION TURU;Po;0;R;;;;;N;;;;; +083C;SAMARITAN PUNCTUATION ARKAANU;Po;0;R;;;;;N;;;;; +083D;SAMARITAN PUNCTUATION SOF MASHFAAT;Po;0;R;;;;;N;;;;; +083E;SAMARITAN PUNCTUATION ANNAAU;Po;0;R;;;;;N;;;;; +0900;DEVANAGARI SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -2036,11 +2100,13 @@ 094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; 094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; 094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +094E;DEVANAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;; 0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;; 0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;; 0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;; 0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; 0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +0955;DEVANAGARI VOWEL SIGN CANDRA LONG E;Mn;0;NSM;;;;;N;;;;; 0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;; 0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;; 095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;; @@ -2068,6 +2134,8 @@ 0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;; 0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;; +0979;DEVANAGARI LETTER ZHA;Lo;0;L;;;;;N;;;;; +097A;DEVANAGARI LETTER HEAVY YA;Lo;0;L;;;;;N;;;;; 097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;; 097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;; 097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;; @@ -2153,17 +2221,18 @@ 09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; -09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;Assamese;;; -09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;Assamese;;; +09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;;;; +09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;;;; 09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;; 09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; -09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1;N;;;;; -09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;2;N;;;;; -09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3;N;;;;; -09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;4;N;;;;; -09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;;N;;;;; +09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1/16;N;;;;; +09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;1/8;N;;;;; +09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3/16;N;;;;; +09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;1/4;N;;;;; +09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;3/4;N;;;;; 09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;; 09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;; +09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;; 0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;; 0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;; 0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -2474,14 +2543,14 @@ 0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;; 0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; 0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; -0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;Naal;;; -0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;Maatham;;; -0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;Varudam;;; -0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;Patru;;; -0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;Varavu;;; -0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;Merpadi;;; -0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;Rupai;;; -0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;Enn;;; +0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;;;; +0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;;;; +0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;;;; +0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;;;; +0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;;;; +0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;;;; +0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;;;; 0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; 0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -2882,7 +2951,7 @@ 0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;; 0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;; 0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;; -0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;paiyan noi;;; +0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;;;; 0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;; 0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;; 0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;; @@ -2890,7 +2959,7 @@ 0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;; 0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;; 0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;; -0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;sara uue;;; +0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;;;; 0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;; 0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;; 0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;; @@ -2898,17 +2967,17 @@ 0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;; 0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;; 0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;; -0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;sara ai mai muan;;; -0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;sara ai mai malai;;; -0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;lakkhang yao;;; -0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;mai yamok;;; -0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;mai taikhu;;; +0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;;;; +0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;;;; +0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;;;; +0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;;;; +0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;;;; 0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;; 0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;; 0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;; 0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;; 0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;; -0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;nikkhahit;;; +0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;;;; 0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;; 0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;; 0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; @@ -2989,37 +3058,37 @@ 0EDC;LAO HO NO;Lo;0;L; 0EAB 0E99;;;;N;;;;; 0EDD;LAO HO MO;Lo;0;L; 0EAB 0EA1;;;;N;;;;; 0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;; -0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;ter yik go a thung;;; -0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;ter yik go wum nam chey ma;;; -0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;ter yik go wum ter tsek ma;;; -0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;yik go dun ma;;; -0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;yik go kab ma;;; -0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;yik go pur shey ma;;; -0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;yik go tsek shey ma;;; -0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;drul shey;;; -0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;kur yik go;;; -0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;ka sho yik go;;; -0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;tsek;;; -0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L; 0F0B;;;;N;;tsek tar;;; -0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;shey;;; -0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;nyi shey;;; -0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;tsek shey;;; -0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;nyi tsek shey;;; -0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;rinchen pung shey;;; -0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;gya tram shey;;; -0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;dzu ta me long chen;;; -0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;ter tsek;;; -0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;che ta;;; -0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;hlak ta;;; -0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;trachen char ta;;; -0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;kyu pa;;; -0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;dong tsu;;; -0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;deka chig;;; -0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;deka nyi;;; -0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;deka sum;;; -0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;dena chig;;; -0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;dena nyi;;; -0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;deka dena;;; +0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;;;; +0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;;;; +0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;;;; +0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;;;; +0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;; +0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;;;; +0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;;;; +0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;;;; +0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;;;; +0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;;;; +0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;;;; +0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L; 0F0B;;;;N;;;;; +0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;;;; +0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;;;; +0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;;;; +0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;;;; +0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;;;; +0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;;;; +0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;;;; +0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;;;; +0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;;;; +0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;;;; +0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;;;; +0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;;;; +0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;;;; +0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;;;; +0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;;;; +0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;;;; +0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;;;; +0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;;;; +0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;;;; 0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -3040,18 +3109,18 @@ 0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;; 0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;; 0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;; -0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;du ta;;; -0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;nge zung nyi da;;; -0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;dzu ta shi mig chen;;; -0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;nge zung gor ta;;; -0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;che go;;; -0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;tsa tru;;; -0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;gug ta yun;;; -0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;gug ta ye;;; -0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;ang kang yun;;; -0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;ang kang ye;;; -0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;yar tse;;; -0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;mar tse;;; +0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;;;; +0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;;;; +0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;;;; +0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;;;; +0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;;;; +0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;;;; +0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;;;; +0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;;;; +0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;;;; +0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;;;; +0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;;;; +0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;;;; 0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;; 0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;; 0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;; @@ -3085,7 +3154,7 @@ 0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;; 0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;; 0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;; -0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;*;;; +0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;;;; 0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;; 0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;; 0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;; @@ -3093,7 +3162,7 @@ 0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;; 0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;; 0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;; -0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;*;;; +0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;;;; 0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;; 0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;; 0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;; @@ -3109,20 +3178,20 @@ 0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;; 0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;; 0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;; -0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;je su nga ro;;; -0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;nam chey;;; +0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;;;; +0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;;;; 0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;; 0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;; -0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;nyi da na da;;; -0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;nan de;;; +0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;;;; +0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;;;; 0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;; 0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;; -0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;ji ta;;; -0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;yang ta;;; -0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;che tsa chen;;; -0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;chu chen;;; -0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;tru chen ging;;; -0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;tru me ging;;; +0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;;;; +0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;;;; +0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;;;; +0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;;;; +0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;;;; +0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;;;; 0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;; 0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;; 0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;; @@ -3151,12 +3220,12 @@ 0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;; 0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;; 0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;; -0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;*;;; +0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;; 0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;; 0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;; 0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;; -0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;*;;; -0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;*;;; +0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;;;; +0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;; 0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;; 0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;; 0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;; @@ -3164,31 +3233,35 @@ 0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;; 0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;; 0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;; -0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;*;;; -0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;*;;; -0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;*;;; -0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;kuruka;;; -0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;kuruka shi mik chen;;; +0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;;;; +0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;;;; +0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;;;; +0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;;;; +0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;;;; 0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;; 0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;; -0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;chang tyu;;; -0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;bub chey;;; -0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;drilbu;;; -0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;dorje;;; -0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;pema den;;; -0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;dorje gya dram;;; -0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;phurba;;; -0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;norbu;;; -0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;norbu nyi khyi;;; -0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;norbu sum khyi;;; -0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;norbu shi khyi;;; -0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;dena deka;;; -0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;dena sum;;; -0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;ka shog gi go gyen;;; -0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;nyam yig gi go gyen;;; -0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;nyi tsek;;; -0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;da nying yik go dun ma;;; -0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;da nying yik go kab ma;;; +0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;;;; +0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;;;; +0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;;;; +0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;;;; +0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;;;; +0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;;;; +0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;;;; +0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;;;; +0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;;;; +0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;;;; +0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;;;; +0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;;;; +0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;;;; +0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;;;; +0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;;;; +0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;;;; +0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;;;; +0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;; +0FD5;RIGHT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;; +0FD6;LEFT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;; +0FD7;RIGHT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;; +0FD8;LEFT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;; 1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;; 1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;; 1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;; @@ -3343,46 +3416,50 @@ 1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +109A;MYANMAR SIGN KHAMTI TONE-1;Mc;0;L;;;;;N;;;;; +109B;MYANMAR SIGN KHAMTI TONE-3;Mc;0;L;;;;;N;;;;; +109C;MYANMAR VOWEL SIGN AITON A;Mc;0;L;;;;;N;;;;; +109D;MYANMAR VOWEL SIGN AITON AI;Mn;0;NSM;;;;;N;;;;; 109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;; 109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;; -10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;Khutsuri;;2D00; -10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;Khutsuri;;2D01; -10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;Khutsuri;;2D02; -10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;Khutsuri;;2D03; -10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;Khutsuri;;2D04; -10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;Khutsuri;;2D05; -10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;Khutsuri;;2D06; -10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;Khutsuri;;2D07; -10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;Khutsuri;;2D08; -10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;Khutsuri;;2D09; -10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;Khutsuri;;2D0A; -10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;Khutsuri;;2D0B; -10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;Khutsuri;;2D0C; -10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;Khutsuri;;2D0D; -10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;Khutsuri;;2D0E; -10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;Khutsuri;;2D0F; -10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;Khutsuri;;2D10; -10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;Khutsuri;;2D11; -10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;Khutsuri;;2D12; -10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;Khutsuri;;2D13; -10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;Khutsuri;;2D14; -10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;Khutsuri;;2D15; -10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;Khutsuri;;2D16; -10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;Khutsuri;;2D17; -10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;Khutsuri;;2D18; -10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;Khutsuri;;2D19; -10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;Khutsuri;;2D1A; -10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;Khutsuri;;2D1B; -10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;Khutsuri;;2D1C; -10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;Khutsuri;;2D1D; -10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;Khutsuri;;2D1E; -10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;Khutsuri;;2D1F; -10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;Khutsuri;;2D20; -10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;Khutsuri;;2D21; -10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;Khutsuri;;2D22; -10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;Khutsuri;;2D23; -10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;Khutsuri;;2D24; -10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;Khutsuri;;2D25; +10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;2D00; +10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;2D01; +10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;2D02; +10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;2D03; +10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;2D04; +10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;2D05; +10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;2D06; +10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;2D07; +10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;2D08; +10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;2D09; +10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;2D0A; +10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;2D0B; +10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;2D0C; +10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;2D0D; +10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;2D0E; +10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;2D0F; +10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;2D10; +10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;2D11; +10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;2D12; +10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;2D13; +10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;2D14; +10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;2D15; +10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;2D16; +10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;2D17; +10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;2D18; +10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;2D19; +10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;2D1A; +10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;2D1B; +10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;2D1C; +10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;2D1D; +10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;2D1E; +10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;2D1F; +10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;2D20; +10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;2D21; +10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;2D22; +10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;2D23; +10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;2D24; +10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25; 10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;; 10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;; 10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;; @@ -3428,25 +3505,25 @@ 10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;; 10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; 10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L; 10DC;;;;N;;;;; -1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; -1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; -1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; -1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; -1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;dd *;;; -1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;r *;;; -1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; -1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; -1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;bb *;;; -1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;s *;;; -110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; +1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;; +1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;; +1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;;;; +1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;;;; +1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;;;; +1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;;;; +1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;; +1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;;;; +110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;; 110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;; -110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; -110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;jj *;;; -110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; -110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; -1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; -1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; -1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; +110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;;;; +110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;; +110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;;;; +110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;;;; +1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;;;; +1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;;;; +1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;;;; 1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; 1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; 1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; @@ -3518,6 +3595,11 @@ 1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; 1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;; 1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +115A;HANGUL CHOSEONG KIYEOK-TIKEUT;Lo;0;L;;;;;N;;;;; +115B;HANGUL CHOSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; +115C;HANGUL CHOSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;; +115D;HANGUL CHOSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;; +115E;HANGUL CHOSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; 115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;; 1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;; 1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;; @@ -3586,33 +3668,38 @@ 11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;; 11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;; 11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;; -11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; -11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; -11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;gs *;;; -11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; -11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;nj *;;; -11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;nh *;;; -11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; -11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;l *;;; -11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;lg *;;; -11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;lm *;;; -11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;lb *;;; -11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;ls *;;; -11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;lt *;;; -11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;lp *;;; -11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;lh *;;; -11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; -11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; -11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;bs *;;; -11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;s *;;; -11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; -11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;ng *;;; -11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; -11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; -11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; -11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; -11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; -11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; +11A3;HANGUL JUNGSEONG A-EU;Lo;0;L;;;;;N;;;;; +11A4;HANGUL JUNGSEONG YA-U;Lo;0;L;;;;;N;;;;; +11A5;HANGUL JUNGSEONG YEO-YA;Lo;0;L;;;;;N;;;;; +11A6;HANGUL JUNGSEONG O-YA;Lo;0;L;;;;;N;;;;; +11A7;HANGUL JUNGSEONG O-YAE;Lo;0;L;;;;;N;;;;; +11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;;;; +11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; +11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;;;; +11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;; +11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;; +11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;;;; +11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;;;; +11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;; +11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;; +11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;; +11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;; +11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;;;; +11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;; +11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; +11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;;;; +11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;;;; +11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;;;; +11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;; +11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;;;; +11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;;;; +11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;;;; +11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;;;; +11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;;;; +11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;;;; +11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;;;; 11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;; 11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; 11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; @@ -3668,6 +3755,12 @@ 11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;; 11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;; 11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +11FA;HANGUL JONGSEONG KIYEOK-NIEUN;Lo;0;L;;;;;N;;;;; +11FB;HANGUL JONGSEONG KIYEOK-PIEUP;Lo;0;L;;;;;N;;;;; +11FC;HANGUL JONGSEONG KIYEOK-CHIEUCH;Lo;0;L;;;;;N;;;;; +11FD;HANGUL JONGSEONG KIYEOK-KHIEUKH;Lo;0;L;;;;;N;;;;; +11FE;HANGUL JONGSEONG KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;; +11FF;HANGUL JONGSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; 1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;; 1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;; 1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;; @@ -4135,6 +4228,7 @@ 13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;; 13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;; 13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;; +1400;CANADIAN SYLLABICS HYPHEN;Pd;0;ON;;;;;N;;;;; 1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;; 1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;; 1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;; @@ -4765,6 +4859,15 @@ 1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;; 1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;; 1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;; +1677;CANADIAN SYLLABICS WOODS-CREE THWEE;Lo;0;L;;;;;N;;;;; +1678;CANADIAN SYLLABICS WOODS-CREE THWI;Lo;0;L;;;;;N;;;;; +1679;CANADIAN SYLLABICS WOODS-CREE THWII;Lo;0;L;;;;;N;;;;; +167A;CANADIAN SYLLABICS WOODS-CREE THWO;Lo;0;L;;;;;N;;;;; +167B;CANADIAN SYLLABICS WOODS-CREE THWOO;Lo;0;L;;;;;N;;;;; +167C;CANADIAN SYLLABICS WOODS-CREE THWA;Lo;0;L;;;;;N;;;;; +167D;CANADIAN SYLLABICS WOODS-CREE THWAA;Lo;0;L;;;;;N;;;;; +167E;CANADIAN SYLLABICS WOODS-CREE FINAL TH;Lo;0;L;;;;;N;;;;; +167F;CANADIAN SYLLABICS BLACKFOOT W;Lo;0;L;;;;;N;;;;; 1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;; 1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;; 1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;; @@ -4872,9 +4975,9 @@ 16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; 16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;; 16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;; -16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;golden number 17;;; -16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;golden number 18;;; -16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;golden number 19;;; +16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;;;; +16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;;;; +16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;;;; 1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;; 1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;; 1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;; @@ -4991,8 +5094,8 @@ 17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;; 17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;; 17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;; -17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;*;;; -17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;*;;; +17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;; +17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;; 17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;; 17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;; 17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;; @@ -5008,8 +5111,8 @@ 17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;; 17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;; 17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;; -17B4;KHMER VOWEL INHERENT AQ;Cf;0;L;;;;;N;;*;;; -17B5;KHMER VOWEL INHERENT AA;Cf;0;L;;;;;N;;*;;; +17B4;KHMER VOWEL INHERENT AQ;Cf;0;L;;;;;N;;;;; +17B5;KHMER VOWEL INHERENT AA;Cf;0;L;;;;;N;;;;; 17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; @@ -5039,12 +5142,12 @@ 17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;; 17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;; 17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;; -17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;*;;; +17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;; 17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;; 17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;; 17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;; 17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;; -17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;*;;; +17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;; 17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;; 17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;; 17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;; @@ -5226,6 +5329,76 @@ 18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;; 18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;; 18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;; +18B0;CANADIAN SYLLABICS OY;Lo;0;L;;;;;N;;;;; +18B1;CANADIAN SYLLABICS AY;Lo;0;L;;;;;N;;;;; +18B2;CANADIAN SYLLABICS AAY;Lo;0;L;;;;;N;;;;; +18B3;CANADIAN SYLLABICS WAY;Lo;0;L;;;;;N;;;;; +18B4;CANADIAN SYLLABICS POY;Lo;0;L;;;;;N;;;;; +18B5;CANADIAN SYLLABICS PAY;Lo;0;L;;;;;N;;;;; +18B6;CANADIAN SYLLABICS PWOY;Lo;0;L;;;;;N;;;;; +18B7;CANADIAN SYLLABICS TAY;Lo;0;L;;;;;N;;;;; +18B8;CANADIAN SYLLABICS KAY;Lo;0;L;;;;;N;;;;; +18B9;CANADIAN SYLLABICS KWAY;Lo;0;L;;;;;N;;;;; +18BA;CANADIAN SYLLABICS MAY;Lo;0;L;;;;;N;;;;; +18BB;CANADIAN SYLLABICS NOY;Lo;0;L;;;;;N;;;;; +18BC;CANADIAN SYLLABICS NAY;Lo;0;L;;;;;N;;;;; +18BD;CANADIAN SYLLABICS LAY;Lo;0;L;;;;;N;;;;; +18BE;CANADIAN SYLLABICS SOY;Lo;0;L;;;;;N;;;;; +18BF;CANADIAN SYLLABICS SAY;Lo;0;L;;;;;N;;;;; +18C0;CANADIAN SYLLABICS SHOY;Lo;0;L;;;;;N;;;;; +18C1;CANADIAN SYLLABICS SHAY;Lo;0;L;;;;;N;;;;; +18C2;CANADIAN SYLLABICS SHWOY;Lo;0;L;;;;;N;;;;; +18C3;CANADIAN SYLLABICS YOY;Lo;0;L;;;;;N;;;;; +18C4;CANADIAN SYLLABICS YAY;Lo;0;L;;;;;N;;;;; +18C5;CANADIAN SYLLABICS RAY;Lo;0;L;;;;;N;;;;; +18C6;CANADIAN SYLLABICS NWI;Lo;0;L;;;;;N;;;;; +18C7;CANADIAN SYLLABICS OJIBWAY NWI;Lo;0;L;;;;;N;;;;; +18C8;CANADIAN SYLLABICS NWII;Lo;0;L;;;;;N;;;;; +18C9;CANADIAN SYLLABICS OJIBWAY NWII;Lo;0;L;;;;;N;;;;; +18CA;CANADIAN SYLLABICS NWO;Lo;0;L;;;;;N;;;;; +18CB;CANADIAN SYLLABICS OJIBWAY NWO;Lo;0;L;;;;;N;;;;; +18CC;CANADIAN SYLLABICS NWOO;Lo;0;L;;;;;N;;;;; +18CD;CANADIAN SYLLABICS OJIBWAY NWOO;Lo;0;L;;;;;N;;;;; +18CE;CANADIAN SYLLABICS RWEE;Lo;0;L;;;;;N;;;;; +18CF;CANADIAN SYLLABICS RWI;Lo;0;L;;;;;N;;;;; +18D0;CANADIAN SYLLABICS RWII;Lo;0;L;;;;;N;;;;; +18D1;CANADIAN SYLLABICS RWO;Lo;0;L;;;;;N;;;;; +18D2;CANADIAN SYLLABICS RWOO;Lo;0;L;;;;;N;;;;; +18D3;CANADIAN SYLLABICS RWA;Lo;0;L;;;;;N;;;;; +18D4;CANADIAN SYLLABICS OJIBWAY P;Lo;0;L;;;;;N;;;;; +18D5;CANADIAN SYLLABICS OJIBWAY T;Lo;0;L;;;;;N;;;;; +18D6;CANADIAN SYLLABICS OJIBWAY K;Lo;0;L;;;;;N;;;;; +18D7;CANADIAN SYLLABICS OJIBWAY C;Lo;0;L;;;;;N;;;;; +18D8;CANADIAN SYLLABICS OJIBWAY M;Lo;0;L;;;;;N;;;;; +18D9;CANADIAN SYLLABICS OJIBWAY N;Lo;0;L;;;;;N;;;;; +18DA;CANADIAN SYLLABICS OJIBWAY S;Lo;0;L;;;;;N;;;;; +18DB;CANADIAN SYLLABICS OJIBWAY SH;Lo;0;L;;;;;N;;;;; +18DC;CANADIAN SYLLABICS EASTERN W;Lo;0;L;;;;;N;;;;; +18DD;CANADIAN SYLLABICS WESTERN W;Lo;0;L;;;;;N;;;;; +18DE;CANADIAN SYLLABICS FINAL SMALL RING;Lo;0;L;;;;;N;;;;; +18DF;CANADIAN SYLLABICS FINAL RAISED DOT;Lo;0;L;;;;;N;;;;; +18E0;CANADIAN SYLLABICS R-CREE RWE;Lo;0;L;;;;;N;;;;; +18E1;CANADIAN SYLLABICS WEST-CREE LOO;Lo;0;L;;;;;N;;;;; +18E2;CANADIAN SYLLABICS WEST-CREE LAA;Lo;0;L;;;;;N;;;;; +18E3;CANADIAN SYLLABICS THWE;Lo;0;L;;;;;N;;;;; +18E4;CANADIAN SYLLABICS THWA;Lo;0;L;;;;;N;;;;; +18E5;CANADIAN SYLLABICS TTHWE;Lo;0;L;;;;;N;;;;; +18E6;CANADIAN SYLLABICS TTHOO;Lo;0;L;;;;;N;;;;; +18E7;CANADIAN SYLLABICS TTHAA;Lo;0;L;;;;;N;;;;; +18E8;CANADIAN SYLLABICS TLHWE;Lo;0;L;;;;;N;;;;; +18E9;CANADIAN SYLLABICS TLHOO;Lo;0;L;;;;;N;;;;; +18EA;CANADIAN SYLLABICS SAYISI SHWE;Lo;0;L;;;;;N;;;;; +18EB;CANADIAN SYLLABICS SAYISI SHOO;Lo;0;L;;;;;N;;;;; +18EC;CANADIAN SYLLABICS SAYISI HOO;Lo;0;L;;;;;N;;;;; +18ED;CANADIAN SYLLABICS CARRIER GWU;Lo;0;L;;;;;N;;;;; +18EE;CANADIAN SYLLABICS CARRIER DENE GEE;Lo;0;L;;;;;N;;;;; +18EF;CANADIAN SYLLABICS CARRIER GAA;Lo;0;L;;;;;N;;;;; +18F0;CANADIAN SYLLABICS CARRIER GWA;Lo;0;L;;;;;N;;;;; +18F1;CANADIAN SYLLABICS SAYISI JUU;Lo;0;L;;;;;N;;;;; +18F2;CANADIAN SYLLABICS CARRIER JWA;Lo;0;L;;;;;N;;;;; +18F3;CANADIAN SYLLABICS BEAVER DENE L;Lo;0;L;;;;;N;;;;; +18F4;CANADIAN SYLLABICS BEAVER DENE R;Lo;0;L;;;;;N;;;;; +18F5;CANADIAN SYLLABICS CARRIER DENTAL S;Lo;0;L;;;;;N;;;;; 1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;; 1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;; 1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;; @@ -5369,6 +5542,8 @@ 19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;; 19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;; 19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;; +19AA;NEW TAI LUE LETTER HIGH SUA;Lo;0;L;;;;;N;;;;; +19AB;NEW TAI LUE LETTER LOW SUA;Lo;0;L;;;;;N;;;;; 19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Mc;0;L;;;;;N;;;;; 19B1;NEW TAI LUE VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 19B2;NEW TAI LUE VOWEL SIGN II;Mc;0;L;;;;;N;;;;; @@ -5405,6 +5580,7 @@ 19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +19DA;NEW TAI LUE THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 19DE;NEW TAI LUE SIGN LAE;Po;0;ON;;;;;N;;;;; 19DF;NEW TAI LUE SIGN LAEV;Po;0;ON;;;;;N;;;;; 19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;; @@ -5469,75 +5645,202 @@ 1A1B;BUGINESE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; 1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;; 1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;; -1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;ardhacandra;;; -1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;candrabindu;;; -1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;anusvara;;; -1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;repha;;; -1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;visarga;;; -1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;a;;; -1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;aa;;; -1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;i;;; -1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;ii;;; -1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;u;;; -1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;uu;;; -1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;vocalic r;;; -1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;vocalic rr;;; -1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;vocalic l;;; -1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;vocalic ll;;; -1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;e;;; -1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;ai;;; -1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;o;;; -1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;au;;; +1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;; +1A21;TAI THAM LETTER HIGH KHA;Lo;0;L;;;;;N;;;;; +1A22;TAI THAM LETTER HIGH KXA;Lo;0;L;;;;;N;;;;; +1A23;TAI THAM LETTER LOW KA;Lo;0;L;;;;;N;;;;; +1A24;TAI THAM LETTER LOW KXA;Lo;0;L;;;;;N;;;;; +1A25;TAI THAM LETTER LOW KHA;Lo;0;L;;;;;N;;;;; +1A26;TAI THAM LETTER NGA;Lo;0;L;;;;;N;;;;; +1A27;TAI THAM LETTER HIGH CA;Lo;0;L;;;;;N;;;;; +1A28;TAI THAM LETTER HIGH CHA;Lo;0;L;;;;;N;;;;; +1A29;TAI THAM LETTER LOW CA;Lo;0;L;;;;;N;;;;; +1A2A;TAI THAM LETTER LOW SA;Lo;0;L;;;;;N;;;;; +1A2B;TAI THAM LETTER LOW CHA;Lo;0;L;;;;;N;;;;; +1A2C;TAI THAM LETTER NYA;Lo;0;L;;;;;N;;;;; +1A2D;TAI THAM LETTER RATA;Lo;0;L;;;;;N;;;;; +1A2E;TAI THAM LETTER HIGH RATHA;Lo;0;L;;;;;N;;;;; +1A2F;TAI THAM LETTER DA;Lo;0;L;;;;;N;;;;; +1A30;TAI THAM LETTER LOW RATHA;Lo;0;L;;;;;N;;;;; +1A31;TAI THAM LETTER RANA;Lo;0;L;;;;;N;;;;; +1A32;TAI THAM LETTER HIGH TA;Lo;0;L;;;;;N;;;;; +1A33;TAI THAM LETTER HIGH THA;Lo;0;L;;;;;N;;;;; +1A34;TAI THAM LETTER LOW TA;Lo;0;L;;;;;N;;;;; +1A35;TAI THAM LETTER LOW THA;Lo;0;L;;;;;N;;;;; +1A36;TAI THAM LETTER NA;Lo;0;L;;;;;N;;;;; +1A37;TAI THAM LETTER BA;Lo;0;L;;;;;N;;;;; +1A38;TAI THAM LETTER HIGH PA;Lo;0;L;;;;;N;;;;; +1A39;TAI THAM LETTER HIGH PHA;Lo;0;L;;;;;N;;;;; +1A3A;TAI THAM LETTER HIGH FA;Lo;0;L;;;;;N;;;;; +1A3B;TAI THAM LETTER LOW PA;Lo;0;L;;;;;N;;;;; +1A3C;TAI THAM LETTER LOW FA;Lo;0;L;;;;;N;;;;; +1A3D;TAI THAM LETTER LOW PHA;Lo;0;L;;;;;N;;;;; +1A3E;TAI THAM LETTER MA;Lo;0;L;;;;;N;;;;; +1A3F;TAI THAM LETTER LOW YA;Lo;0;L;;;;;N;;;;; +1A40;TAI THAM LETTER HIGH YA;Lo;0;L;;;;;N;;;;; +1A41;TAI THAM LETTER RA;Lo;0;L;;;;;N;;;;; +1A42;TAI THAM LETTER RUE;Lo;0;L;;;;;N;;;;; +1A43;TAI THAM LETTER LA;Lo;0;L;;;;;N;;;;; +1A44;TAI THAM LETTER LUE;Lo;0;L;;;;;N;;;;; +1A45;TAI THAM LETTER WA;Lo;0;L;;;;;N;;;;; +1A46;TAI THAM LETTER HIGH SHA;Lo;0;L;;;;;N;;;;; +1A47;TAI THAM LETTER HIGH SSA;Lo;0;L;;;;;N;;;;; +1A48;TAI THAM LETTER HIGH SA;Lo;0;L;;;;;N;;;;; +1A49;TAI THAM LETTER HIGH HA;Lo;0;L;;;;;N;;;;; +1A4A;TAI THAM LETTER LLA;Lo;0;L;;;;;N;;;;; +1A4B;TAI THAM LETTER A;Lo;0;L;;;;;N;;;;; +1A4C;TAI THAM LETTER LOW HA;Lo;0;L;;;;;N;;;;; +1A4D;TAI THAM LETTER I;Lo;0;L;;;;;N;;;;; +1A4E;TAI THAM LETTER II;Lo;0;L;;;;;N;;;;; +1A4F;TAI THAM LETTER U;Lo;0;L;;;;;N;;;;; +1A50;TAI THAM LETTER UU;Lo;0;L;;;;;N;;;;; +1A51;TAI THAM LETTER EE;Lo;0;L;;;;;N;;;;; +1A52;TAI THAM LETTER OO;Lo;0;L;;;;;N;;;;; +1A53;TAI THAM LETTER LAE;Lo;0;L;;;;;N;;;;; +1A54;TAI THAM LETTER GREAT SA;Lo;0;L;;;;;N;;;;; +1A55;TAI THAM CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;; +1A56;TAI THAM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;; +1A57;TAI THAM CONSONANT SIGN LA TANG LAI;Mc;0;L;;;;;N;;;;; +1A58;TAI THAM SIGN MAI KANG LAI;Mn;0;NSM;;;;;N;;;;; +1A59;TAI THAM CONSONANT SIGN FINAL NGA;Mn;0;NSM;;;;;N;;;;; +1A5A;TAI THAM CONSONANT SIGN LOW PA;Mn;0;NSM;;;;;N;;;;; +1A5B;TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA;Mn;0;NSM;;;;;N;;;;; +1A5C;TAI THAM CONSONANT SIGN MA;Mn;0;NSM;;;;;N;;;;; +1A5D;TAI THAM CONSONANT SIGN BA;Mn;0;NSM;;;;;N;;;;; +1A5E;TAI THAM CONSONANT SIGN SA;Mn;0;NSM;;;;;N;;;;; +1A60;TAI THAM SIGN SAKOT;Mn;9;NSM;;;;;N;;;;; +1A61;TAI THAM VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +1A62;TAI THAM VOWEL SIGN MAI SAT;Mn;0;NSM;;;;;N;;;;; +1A63;TAI THAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1A64;TAI THAM VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;; +1A65;TAI THAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1A66;TAI THAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +1A67;TAI THAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +1A68;TAI THAM VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;; +1A69;TAI THAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1A6A;TAI THAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1A6B;TAI THAM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +1A6C;TAI THAM VOWEL SIGN OA BELOW;Mn;0;NSM;;;;;N;;;;; +1A6D;TAI THAM VOWEL SIGN OY;Mc;0;L;;;;;N;;;;; +1A6E;TAI THAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1A6F;TAI THAM VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +1A70;TAI THAM VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1A71;TAI THAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +1A72;TAI THAM VOWEL SIGN THAM AI;Mc;0;L;;;;;N;;;;; +1A73;TAI THAM VOWEL SIGN OA ABOVE;Mn;0;NSM;;;;;N;;;;; +1A74;TAI THAM SIGN MAI KANG;Mn;0;NSM;;;;;N;;;;; +1A75;TAI THAM SIGN TONE-1;Mn;230;NSM;;;;;N;;;;; +1A76;TAI THAM SIGN TONE-2;Mn;230;NSM;;;;;N;;;;; +1A77;TAI THAM SIGN KHUEN TONE-3;Mn;230;NSM;;;;;N;;;;; +1A78;TAI THAM SIGN KHUEN TONE-4;Mn;230;NSM;;;;;N;;;;; +1A79;TAI THAM SIGN KHUEN TONE-5;Mn;230;NSM;;;;;N;;;;; +1A7A;TAI THAM SIGN RA HAAM;Mn;230;NSM;;;;;N;;;;; +1A7B;TAI THAM SIGN MAI SAM;Mn;230;NSM;;;;;N;;;;; +1A7C;TAI THAM SIGN KHUEN-LUE KARAN;Mn;230;NSM;;;;;N;;;;; +1A7F;TAI THAM COMBINING CRYPTOGRAMMIC DOT;Mn;220;NSM;;;;;N;;;;; +1A80;TAI THAM HORA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1A81;TAI THAM HORA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1A82;TAI THAM HORA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1A83;TAI THAM HORA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1A84;TAI THAM HORA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1A85;TAI THAM HORA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1A86;TAI THAM HORA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1A87;TAI THAM HORA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1A88;TAI THAM HORA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1A89;TAI THAM HORA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1A90;TAI THAM THAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1A91;TAI THAM THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1A92;TAI THAM THAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1A93;TAI THAM THAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1A94;TAI THAM THAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1A95;TAI THAM THAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1A96;TAI THAM THAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1A97;TAI THAM THAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1A98;TAI THAM THAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1A99;TAI THAM THAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1AA0;TAI THAM SIGN WIANG;Po;0;L;;;;;N;;;;; +1AA1;TAI THAM SIGN WIANGWAAK;Po;0;L;;;;;N;;;;; +1AA2;TAI THAM SIGN SAWAN;Po;0;L;;;;;N;;;;; +1AA3;TAI THAM SIGN KEOW;Po;0;L;;;;;N;;;;; +1AA4;TAI THAM SIGN HOY;Po;0;L;;;;;N;;;;; +1AA5;TAI THAM SIGN DOKMAI;Po;0;L;;;;;N;;;;; +1AA6;TAI THAM SIGN REVERSED ROTATED RANA;Po;0;L;;;;;N;;;;; +1AA7;TAI THAM SIGN MAI YAMOK;Lm;0;L;;;;;N;;;;; +1AA8;TAI THAM SIGN KAAN;Po;0;L;;;;;N;;;;; +1AA9;TAI THAM SIGN KAANKUU;Po;0;L;;;;;N;;;;; +1AAA;TAI THAM SIGN SATKAAN;Po;0;L;;;;;N;;;;; +1AAB;TAI THAM SIGN SATKAANKUU;Po;0;L;;;;;N;;;;; +1AAC;TAI THAM SIGN HANG;Po;0;L;;;;;N;;;;; +1AAD;TAI THAM SIGN CAANG;Po;0;L;;;;;N;;;;; +1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;; +1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;; +1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;; +1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;;;; +1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;;;; +1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;;;; +1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;;;; +1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;;;; +1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;;;; +1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;;;; +1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;;;; +1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;;;; +1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;;;; +1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;;;; +1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;;;; +1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;;;; +1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;;;; +1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;;;; +1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;;;; 1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;; -1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;kha;;; +1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;;;; 1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;; -1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;gha;;; +1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;;;; 1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;; 1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;; -1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;cha;;; +1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;;;; 1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;; -1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;jha;;; +1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;;;; 1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;; -1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;tta;;; -1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;ttha;;; -1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;dda;;; -1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;ddha;;; -1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;nna;;; +1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;;;; +1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;;;; +1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;;;; 1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;; -1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;tha;;; +1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;;;; 1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;; -1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;dha;;; +1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;;;; 1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;; 1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;; -1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;pha;;; +1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;;;; 1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;; -1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;bha;;; +1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;;;; 1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;; 1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;; 1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;; 1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;; 1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;; -1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;sha;;; -1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;ssa;;; +1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;;;; +1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;;;; 1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;; 1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;; -1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;nukta;;; -1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;aa;;; -1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;i;;; -1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;ii;;; -1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;u;;; -1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;uu;;; -1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;vocalic r;;; -1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;vocalic rr;;; -1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;vocalic l;;; -1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;vocalic ll;;; -1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;e;;; -1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;ai;;; -1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;o;;; -1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;au;;; -1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;ae;;; -1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;oe;;; -1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;virama;;; +1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;;;; +1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;;;; +1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;;;; +1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;;;; +1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;; +1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;;;; +1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;;;; +1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;;;; +1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;;;; +1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;;;; +1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; +1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;;;; +1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;;;; +1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;;;; +1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; +1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;;;; +1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;;;; 1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;; 1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;; 1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;; @@ -5555,13 +5858,13 @@ 1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; -1B5A;BALINESE PANTI;Po;0;L;;;;;N;;section;;; -1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;honorific section;;; -1B5C;BALINESE WINDU;Po;0;L;;;;;N;;punctuation ring;;; -1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;colon;;; -1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;danda;;; -1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;double danda;;; -1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;line-breaking hyphen;;; +1B5A;BALINESE PANTI;Po;0;L;;;;;N;;;;; +1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;;;; +1B5C;BALINESE WINDU;Po;0;L;;;;;N;;;;; +1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;;;; +1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;;;; +1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;;;; +1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;;;; 1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;; 1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;; 1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;; @@ -5767,6 +6070,41 @@ 1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;; 1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;; 1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;; +1CD0;VEDIC TONE KARSHANA;Mn;230;NSM;;;;;N;;;;; +1CD1;VEDIC TONE SHARA;Mn;230;NSM;;;;;N;;;;; +1CD2;VEDIC TONE PRENKHA;Mn;230;NSM;;;;;N;;;;; +1CD3;VEDIC SIGN NIHSHVASA;Po;0;L;;;;;N;;;;; +1CD4;VEDIC SIGN YAJURVEDIC MIDLINE SVARITA;Mn;1;NSM;;;;;N;;;;; +1CD5;VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD6;VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD7;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD8;VEDIC TONE CANDRA BELOW;Mn;220;NSM;;;;;N;;;;; +1CD9;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER;Mn;220;NSM;;;;;N;;;;; +1CDA;VEDIC TONE DOUBLE SVARITA;Mn;230;NSM;;;;;N;;;;; +1CDB;VEDIC TONE TRIPLE SVARITA;Mn;230;NSM;;;;;N;;;;; +1CDC;VEDIC TONE KATHAKA ANUDATTA;Mn;220;NSM;;;;;N;;;;; +1CDD;VEDIC TONE DOT BELOW;Mn;220;NSM;;;;;N;;;;; +1CDE;VEDIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +1CDF;VEDIC TONE THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +1CE0;VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA;Mn;230;NSM;;;;;N;;;;; +1CE1;VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA;Mc;0;L;;;;;N;;;;; +1CE2;VEDIC SIGN VISARGA SVARITA;Mn;1;NSM;;;;;N;;;;; +1CE3;VEDIC SIGN VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;; +1CE4;VEDIC SIGN REVERSED VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;; +1CE5;VEDIC SIGN VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;; +1CE6;VEDIC SIGN REVERSED VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;; +1CE7;VEDIC SIGN VISARGA UDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;; +1CE8;VEDIC SIGN VISARGA ANUDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;; +1CE9;VEDIC SIGN ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEA;VEDIC SIGN ANUSVARA BAHIRGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEB;VEDIC SIGN ANUSVARA VAMAGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEC;VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL;Lo;0;L;;;;;N;;;;; +1CED;VEDIC SIGN TIRYAK;Mn;220;NSM;;;;;N;;;;; +1CEE;VEDIC SIGN HEXIFORM LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;; +1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;; 1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;; 1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;; 1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;; @@ -5998,6 +6336,7 @@ 1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;; 1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;; 1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;; +1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;; 1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; 1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; 1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01; @@ -6552,7 +6891,7 @@ 203C;DOUBLE EXCLAMATION MARK;Po;0;ON; 0021 0021;;;;N;;;;; 203D;INTERROBANG;Po;0;ON;;;;;N;;;;; 203E;OVERLINE;Po;0;ON; 0020 0305;;;;N;SPACING OVERSCORE;;;; -203F;UNDERTIE;Pc;0;ON;;;;;N;;Enotikon;;; +203F;UNDERTIE;Pc;0;ON;;;;;N;;;;; 2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;; 2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;; 2042;ASTERISM;Po;0;ON;;;;;N;;;;; @@ -6597,7 +6936,7 @@ 206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; 206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; 2070;SUPERSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;; -2071;SUPERSCRIPT LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;;; +2071;SUPERSCRIPT LATIN SMALL LETTER I;Lm;0;L; 0069;;;;N;;;;; 2074;SUPERSCRIPT FOUR;No;0;EN; 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;; 2075;SUPERSCRIPT FIVE;No;0;EN; 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;; 2076;SUPERSCRIPT SIX;No;0;EN; 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;; @@ -6609,7 +6948,7 @@ 207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; 207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;; 207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;; -207F;SUPERSCRIPT LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;;; +207F;SUPERSCRIPT LATIN SMALL LETTER N;Lm;0;L; 006E;;;;N;;;;; 2080;SUBSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;; 2081;SUBSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;; 2082;SUBSCRIPT TWO;No;0;EN; 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;; @@ -6652,6 +6991,9 @@ 20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;; 20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;; 20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;; +20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;; +20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;; +20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;; 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; @@ -6765,6 +7107,9 @@ 214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;; 214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132 214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;; +2150;VULGAR FRACTION ONE SEVENTH;No;0;ON; 0031 2044 0037;;;1/7;N;;;;; +2151;VULGAR FRACTION ONE NINTH;No;0;ON; 0031 2044 0039;;;1/9;N;;;;; +2152;VULGAR FRACTION ONE TENTH;No;0;ON; 0031 2044 0031 0030;;;1/10;N;;;;; 2153;VULGAR FRACTION ONE THIRD;No;0;ON; 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;; 2154;VULGAR FRACTION TWO THIRDS;No;0;ON; 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;; 2155;VULGAR FRACTION ONE FIFTH;No;0;ON; 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;; @@ -6819,6 +7164,7 @@ 2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;; 2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;; 2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;; +2189;VULGAR FRACTION ZERO THIRDS;No;0;ON; 0030 2044 0033;;;0;N;;;;; 2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;; 2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;; 2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;; @@ -6992,7 +7338,7 @@ 223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;; 223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;; 223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; -223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;lazy S;;; +223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;;;; 223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;; 223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;; 2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;; @@ -7261,18 +7607,18 @@ 2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;; 2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;; 2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;; -234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;*;;; +234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;;;; 234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;; 234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;; 234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;; -234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;*;;; +234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;;;; 234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;; 2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;; -2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;*;;; +2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;;;; 2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;; 2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;; 2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;; -2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;*;;; +2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;;;; 2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;; 2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;; 2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;; @@ -7284,7 +7630,7 @@ 235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;; 235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;; 2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;; -2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;*;;; +2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;;;; 2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;; 2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;; 2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;; @@ -7324,9 +7670,9 @@ 2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;; 2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;; 2388;HELM SYMBOL;So;0;ON;;;;;N;;;;; -2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;pause;;; -238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;break;;; -238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;escape;;; +2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;;;; +238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;;;; +238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;;;; 238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;; 238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;; 238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;; @@ -7407,18 +7753,19 @@ 23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;; 23DA;EARTH GROUND;So;0;ON;;;;;N;;;;; 23DB;FUSE;So;0;ON;;;;;N;;;;; -23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;mathematical use;;; -23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;mathematical use;;; -23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; -23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; -23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; -23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;mathematical use;;; +23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;;;; +23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;;;; +23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;;;; +23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;;;; +23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;; +23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;; 23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;; 23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;; 23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;; 23E5;FLATNESS;So;0;ON;;;;;N;;;;; 23E6;AC CURRENT;So;0;ON;;;;;N;;;;; 23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;; +23E8;DECIMAL EXPONENT SYMBOL;So;0;ON;;;;;N;;;;; 2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;; 2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;; 2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;; @@ -8000,13 +8347,13 @@ 2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;; 2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;; 2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; -2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;pete;;; -2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;hdpe;;; -2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;pvc;;; -2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;ldpe;;; -2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;pp;;; -2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;ps;;; -2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;other;;; +2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;;;; +2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;;;; +2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;;;; +2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;;;; +2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;;;; +2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;;;; +2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;;;; 267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;; 267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; 267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; @@ -8043,6 +8390,8 @@ 269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;; 269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;; 269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +269E;THREE LINES CONVERGING RIGHT;So;0;ON;;;;;N;;;;; +269F;THREE LINES CONVERGING LEFT;So;0;ON;;;;;N;;;;; 26A0;WARNING SIGN;So;0;ON;;;;;N;;;;; 26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;; 26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;; @@ -8072,10 +8421,67 @@ 26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;; 26BB;QUINCUNX;So;0;ON;;;;;N;;;;; 26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;; +26BD;SOCCER BALL;So;0;ON;;;;;N;;;;; +26BE;BASEBALL;So;0;ON;;;;;N;;;;; +26BF;SQUARED KEY;So;0;ON;;;;;N;;;;; 26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;; 26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;; 26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;; 26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;; +26C4;SNOWMAN WITHOUT SNOW;So;0;ON;;;;;N;;;;; +26C5;SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;; +26C6;RAIN;So;0;ON;;;;;N;;;;; +26C7;BLACK SNOWMAN;So;0;ON;;;;;N;;;;; +26C8;THUNDER CLOUD AND RAIN;So;0;ON;;;;;N;;;;; +26C9;TURNED WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; +26CA;TURNED BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; +26CB;WHITE DIAMOND IN SQUARE;So;0;ON;;;;;N;;;;; +26CC;CROSSING LANES;So;0;ON;;;;;N;;;;; +26CD;DISABLED CAR;So;0;ON;;;;;N;;;;; +26CF;PICK;So;0;ON;;;;;N;;;;; +26D0;CAR SLIDING;So;0;ON;;;;;N;;;;; +26D1;HELMET WITH WHITE CROSS;So;0;ON;;;;;N;;;;; +26D2;CIRCLED CROSSING LANES;So;0;ON;;;;;N;;;;; +26D3;CHAINS;So;0;ON;;;;;N;;;;; +26D4;NO ENTRY;So;0;ON;;;;;N;;;;; +26D5;ALTERNATE ONE-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D6;BLACK TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D7;WHITE TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D8;BLACK LEFT LANE MERGE;So;0;ON;;;;;N;;;;; +26D9;WHITE LEFT LANE MERGE;So;0;ON;;;;;N;;;;; +26DA;DRIVE SLOW SIGN;So;0;ON;;;;;N;;;;; +26DB;HEAVY WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +26DC;LEFT CLOSED ENTRY;So;0;ON;;;;;N;;;;; +26DD;SQUARED SALTIRE;So;0;ON;;;;;N;;;;; +26DE;FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE;So;0;ON;;;;;N;;;;; +26DF;BLACK TRUCK;So;0;ON;;;;;N;;;;; +26E0;RESTRICTED LEFT ENTRY-1;So;0;ON;;;;;N;;;;; +26E1;RESTRICTED LEFT ENTRY-2;So;0;ON;;;;;N;;;;; +26E3;HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE;So;0;ON;;;;;N;;;;; +26E8;BLACK CROSS ON SHIELD;So;0;ON;;;;;N;;;;; +26E9;SHINTO SHRINE;So;0;ON;;;;;N;;;;; +26EA;CHURCH;So;0;ON;;;;;N;;;;; +26EB;CASTLE;So;0;ON;;;;;N;;;;; +26EC;HISTORIC SITE;So;0;ON;;;;;N;;;;; +26ED;GEAR WITHOUT HUB;So;0;ON;;;;;N;;;;; +26EE;GEAR WITH HANDLES;So;0;ON;;;;;N;;;;; +26EF;MAP SYMBOL FOR LIGHTHOUSE;So;0;ON;;;;;N;;;;; +26F0;MOUNTAIN;So;0;ON;;;;;N;;;;; +26F1;UMBRELLA ON GROUND;So;0;ON;;;;;N;;;;; +26F2;FOUNTAIN;So;0;ON;;;;;N;;;;; +26F3;FLAG IN HOLE;So;0;ON;;;;;N;;;;; +26F4;FERRY;So;0;ON;;;;;N;;;;; +26F5;SAILBOAT;So;0;ON;;;;;N;;;;; +26F6;SQUARE FOUR CORNERS;So;0;ON;;;;;N;;;;; +26F7;SKIER;So;0;ON;;;;;N;;;;; +26F8;ICE SKATE;So;0;ON;;;;;N;;;;; +26F9;PERSON WITH BALL;So;0;ON;;;;;N;;;;; +26FA;TENT;So;0;ON;;;;;N;;;;; +26FB;JAPANESE BANK SYMBOL;So;0;ON;;;;;N;;;;; +26FC;HEADSTONE GRAVEYARD SYMBOL;So;0;ON;;;;;N;;;;; +26FD;FUEL PUMP;So;0;ON;;;;;N;;;;; +26FE;CUP ON BLACK SQUARE;So;0;ON;;;;;N;;;;; +26FF;WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE;So;0;ON;;;;;N;;;;; 2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;; 2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;; 2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;; @@ -8153,6 +8559,7 @@ 2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; 2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; 2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;; +2757;HEAVY EXCLAMATION MARK SYMBOL;So;0;ON;;;;;N;;;;; 2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;; 2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;; 275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;; @@ -9042,8 +9449,8 @@ 2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;; 2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;; 2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;; -2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;not independent;;; -2ADD;NONFORKING;Sm;0;ON;;;;;N;;independent;;; +2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;;;; +2ADD;NONFORKING;Sm;0;ON;;;;;N;;;;; 2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;; 2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; 2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;; @@ -9160,6 +9567,11 @@ 2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;; 2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; 2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; +2B55;HEAVY LARGE CIRCLE;So;0;ON;;;;;N;;;;; +2B56;HEAVY OVAL WITH OVAL INSIDE;So;0;ON;;;;;N;;;;; +2B57;HEAVY CIRCLE WITH CIRCLE INSIDE;So;0;ON;;;;;N;;;;; +2B58;HEAVY CIRCLE;So;0;ON;;;;;N;;;;; +2B59;HEAVY CIRCLED SALTIRE;So;0;ON;;;;;N;;;;; 2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30; 2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31; 2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32; @@ -9270,6 +9682,7 @@ 2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251; 2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271; 2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250; +2C70;LATIN CAPITAL LETTER TURNED ALPHA;Lu;0;L;;;;;N;;;;0252; 2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;; 2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73; 2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72 @@ -9283,6 +9696,8 @@ 2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;; 2C7C;LATIN SUBSCRIPT SMALL LETTER J;Ll;0;L; 006A;;;;N;;;;; 2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L; 0056;;;;N;;;;; +2C7E;LATIN CAPITAL LETTER S WITH SWASH TAIL;Lu;0;L;;;;;N;;;;023F; +2C7F;LATIN CAPITAL LETTER Z WITH SWASH TAIL;Lu;0;L;;;;;N;;;;0240; 2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81; 2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80 2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83; @@ -9390,6 +9805,13 @@ 2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;; 2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;; 2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;; +2CEB;COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI;Lu;0;L;;;;;N;;;;2CEC; +2CEC;COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI;Ll;0;L;;;;;N;;;2CEB;;2CEB +2CED;COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA;Lu;0;L;;;;;N;;;;2CEE; +2CEE;COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA;Ll;0;L;;;;;N;;;2CED;;2CED +2CEF;COPTIC COMBINING NI ABOVE;Mn;230;NSM;;;;;N;;;;; +2CF0;COPTIC COMBINING SPIRITUS ASPER;Mn;230;NSM;;;;;N;;;;; +2CF1;COPTIC COMBINING SPIRITUS LENIS;Mn;230;NSM;;;;;N;;;;; 2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;; 2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; 2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; @@ -9397,44 +9819,44 @@ 2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;; 2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;; 2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;; -2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;Khutsuri;10A0;;10A0 -2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;Khutsuri;10A1;;10A1 -2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;Khutsuri;10A2;;10A2 -2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;Khutsuri;10A3;;10A3 -2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;Khutsuri;10A4;;10A4 -2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;Khutsuri;10A5;;10A5 -2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;Khutsuri;10A6;;10A6 -2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;Khutsuri;10A7;;10A7 -2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;Khutsuri;10A8;;10A8 -2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;Khutsuri;10A9;;10A9 -2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;Khutsuri;10AA;;10AA -2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;Khutsuri;10AB;;10AB -2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;Khutsuri;10AC;;10AC -2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;Khutsuri;10AD;;10AD -2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;Khutsuri;10AE;;10AE -2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;Khutsuri;10AF;;10AF -2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;Khutsuri;10B0;;10B0 -2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;Khutsuri;10B1;;10B1 -2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;Khutsuri;10B2;;10B2 -2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;Khutsuri;10B3;;10B3 -2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;Khutsuri;10B4;;10B4 -2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;Khutsuri;10B5;;10B5 -2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;Khutsuri;10B6;;10B6 -2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;Khutsuri;10B7;;10B7 -2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;Khutsuri;10B8;;10B8 -2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;Khutsuri;10B9;;10B9 -2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;Khutsuri;10BA;;10BA -2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;Khutsuri;10BB;;10BB -2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;Khutsuri;10BC;;10BC -2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;Khutsuri;10BD;;10BD -2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;Khutsuri;10BE;;10BE -2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;Khutsuri;10BF;;10BF -2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;Khutsuri;10C0;;10C0 -2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;Khutsuri;10C1;;10C1 -2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;Khutsuri;10C2;;10C2 -2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;Khutsuri;10C3;;10C3 -2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;Khutsuri;10C4;;10C4 -2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;Khutsuri;10C5;;10C5 +2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;;10A0;;10A0 +2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;;10A1;;10A1 +2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;;10A2;;10A2 +2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;;10A3;;10A3 +2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;;10A4;;10A4 +2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;;10A5;;10A5 +2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;;10A6;;10A6 +2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;;10A7;;10A7 +2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;;10A8;;10A8 +2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;;10A9;;10A9 +2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;;10AA;;10AA +2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;;10AB;;10AB +2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;;10AC;;10AC +2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;;10AD;;10AD +2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;;10AE;;10AE +2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;;10AF;;10AF +2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;;10B0;;10B0 +2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;;10B1;;10B1 +2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;;10B2;;10B2 +2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;;10B3;;10B3 +2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;;10B4;;10B4 +2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;;10B5;;10B5 +2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;;10B6;;10B6 +2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;;10B7;;10B7 +2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;;10B8;;10B8 +2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;;10B9;;10B9 +2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;;10BA;;10BA +2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;;10BB;;10BB +2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;;10BC;;10BC +2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;;10BD;;10BD +2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;;10BE;;10BE +2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;;10BF;;10BF +2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;;10C0;;10C0 +2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;;10C1;;10C1 +2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;;10C2;;10C2 +2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;;10C3;;10C3 +2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;;10C4;;10C4 +2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;;10C5;;10C5 2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;; 2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;; 2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;; @@ -9451,7 +9873,7 @@ 2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;; 2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;; 2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;; -2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;Tuareg yab;;; +2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;;;; 2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;; 2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;; 2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;; @@ -9470,12 +9892,12 @@ 2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;; 2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;; 2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;; -2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;Tuareg yaw;;; +2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;;;; 2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;; 2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;; 2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;; 2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;; -2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;Adrar yaj;;; +2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;;;; 2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;; 2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;; 2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;; @@ -9487,9 +9909,9 @@ 2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;; 2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;; 2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;; -2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;harpoon yaz;;; +2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;;;; 2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;; -2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L; 2D61;;;;N;;tamatart;;; +2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L; 2D61;;;;N;;;;; 2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;; 2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;; 2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;; @@ -9650,6 +10072,7 @@ 2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;; 2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;; 2E30;RING POINT;Po;0;ON;;;;;N;;;;; +2E31;WORD SEPARATOR MIDDLE DOT;Po;0;ON;;;;;N;;;;; 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; @@ -10379,22 +10802,22 @@ 318C;HANGUL LETTER YU-I;Lo;0;L; 1194;;;;N;HANGUL LETTER YUI;;;; 318D;HANGUL LETTER ARAEA;Lo;0;L; 119E;;;;N;HANGUL LETTER ALAE A;;;; 318E;HANGUL LETTER ARAEAE;Lo;0;L; 11A1;;;;N;HANGUL LETTER ALAE AE;;;; -3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;Kanbun Tateten;;; -3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;Kaeriten;;; -3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L; 4E00;;;1;N;KAERITEN ITI;Kaeriten;;; -3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L; 4E8C;;;2;N;KAERITEN NI;Kaeriten;;; -3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L; 4E09;;;3;N;KAERITEN SAN;Kaeriten;;; -3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L; 56DB;;;4;N;KAERITEN SI;Kaeriten;;; -3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L; 4E0A;;;;N;KAERITEN ZYOU;Kaeriten;;; -3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L; 4E2D;;;;N;KAERITEN TYUU;Kaeriten;;; -3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L; 4E0B;;;;N;KAERITEN GE;Kaeriten;;; -3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L; 7532;;;;N;KAERITEN KOU;Kaeriten;;; -319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L; 4E59;;;;N;KAERITEN OTU;Kaeriten;;; -319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L; 4E19;;;;N;KAERITEN HEI;Kaeriten;;; -319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L; 4E01;;;;N;KAERITEN TEI;Kaeriten;;; -319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L; 5929;;;;N;KAERITEN TEN;Kaeriten;;; -319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L; 5730;;;;N;KAERITEN TI;Kaeriten;;; -319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L; 4EBA;;;;N;KAERITEN ZIN;Kaeriten;;; +3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;;;; +3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;;;; +3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L; 4E00;;;1;N;KAERITEN ITI;;;; +3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L; 4E8C;;;2;N;KAERITEN NI;;;; +3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L; 4E09;;;3;N;KAERITEN SAN;;;; +3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L; 56DB;;;4;N;KAERITEN SI;;;; +3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L; 4E0A;;;;N;KAERITEN ZYOU;;;; +3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L; 4E2D;;;;N;KAERITEN TYUU;;;; +3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L; 4E0B;;;;N;KAERITEN GE;;;; +3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L; 7532;;;;N;KAERITEN KOU;;;; +319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L; 4E59;;;;N;KAERITEN OTU;;;; +319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L; 4E19;;;;N;KAERITEN HEI;;;; +319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L; 4E01;;;;N;KAERITEN TEI;;;; +319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L; 5929;;;;N;KAERITEN TEN;;;; +319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L; 5730;;;;N;KAERITEN TI;;;; +319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L; 4EBA;;;;N;KAERITEN ZIN;;;; 31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;; 31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;; 31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;; @@ -10538,6 +10961,18 @@ 3241;PARENTHESIZED IDEOGRAPH REST;So;0;L; 0028 4F11 0029;;;;N;;;;; 3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L; 0028 81EA 0029;;;;N;;;;; 3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L; 0028 81F3 0029;;;;N;;;;; +3244;CIRCLED IDEOGRAPH QUESTION;So;0;L; 554F;;;;N;;;;; +3245;CIRCLED IDEOGRAPH KINDERGARTEN;So;0;L; 5E7C;;;;N;;;;; +3246;CIRCLED IDEOGRAPH SCHOOL;So;0;L; 6587;;;;N;;;;; +3247;CIRCLED IDEOGRAPH KOTO;So;0;L; 7B8F;;;;N;;;;; +3248;CIRCLED NUMBER TEN ON BLACK SQUARE;So;0;L;;;;;N;;;;; +3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; +324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;So;0;L;;;;;N;;;;; 3250;PARTNERSHIP SIGN;So;0;ON; 0050 0054 0045;;;;N;;;;; 3251;CIRCLED NUMBER TWENTY ONE;No;0;ON; 0032 0031;;;21;N;;;;; 3252;CIRCLED NUMBER TWENTY TWO;No;0;ON; 0032 0032;;;22;N;;;;; @@ -11036,7 +11471,7 @@ 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;; 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;; 4E00;;Lo;0;L;;;;;N;;;;; -9FC3;;Lo;0;L;;;;;N;;;;; +9FCB;;Lo;0;L;;;;;N;;;;; A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; @@ -12257,6 +12692,54 @@ A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;; A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;; A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;; A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;; +A4D0;LISU LETTER BA;Lo;0;L;;;;;N;;;;; +A4D1;LISU LETTER PA;Lo;0;L;;;;;N;;;;; +A4D2;LISU LETTER PHA;Lo;0;L;;;;;N;;;;; +A4D3;LISU LETTER DA;Lo;0;L;;;;;N;;;;; +A4D4;LISU LETTER TA;Lo;0;L;;;;;N;;;;; +A4D5;LISU LETTER THA;Lo;0;L;;;;;N;;;;; +A4D6;LISU LETTER GA;Lo;0;L;;;;;N;;;;; +A4D7;LISU LETTER KA;Lo;0;L;;;;;N;;;;; +A4D8;LISU LETTER KHA;Lo;0;L;;;;;N;;;;; +A4D9;LISU LETTER JA;Lo;0;L;;;;;N;;;;; +A4DA;LISU LETTER CA;Lo;0;L;;;;;N;;;;; +A4DB;LISU LETTER CHA;Lo;0;L;;;;;N;;;;; +A4DC;LISU LETTER DZA;Lo;0;L;;;;;N;;;;; +A4DD;LISU LETTER TSA;Lo;0;L;;;;;N;;;;; +A4DE;LISU LETTER TSHA;Lo;0;L;;;;;N;;;;; +A4DF;LISU LETTER MA;Lo;0;L;;;;;N;;;;; +A4E0;LISU LETTER NA;Lo;0;L;;;;;N;;;;; +A4E1;LISU LETTER LA;Lo;0;L;;;;;N;;;;; +A4E2;LISU LETTER SA;Lo;0;L;;;;;N;;;;; +A4E3;LISU LETTER ZHA;Lo;0;L;;;;;N;;;;; +A4E4;LISU LETTER ZA;Lo;0;L;;;;;N;;;;; +A4E5;LISU LETTER NGA;Lo;0;L;;;;;N;;;;; +A4E6;LISU LETTER HA;Lo;0;L;;;;;N;;;;; +A4E7;LISU LETTER XA;Lo;0;L;;;;;N;;;;; +A4E8;LISU LETTER HHA;Lo;0;L;;;;;N;;;;; +A4E9;LISU LETTER FA;Lo;0;L;;;;;N;;;;; +A4EA;LISU LETTER WA;Lo;0;L;;;;;N;;;;; +A4EB;LISU LETTER SHA;Lo;0;L;;;;;N;;;;; +A4EC;LISU LETTER YA;Lo;0;L;;;;;N;;;;; +A4ED;LISU LETTER GHA;Lo;0;L;;;;;N;;;;; +A4EE;LISU LETTER A;Lo;0;L;;;;;N;;;;; +A4EF;LISU LETTER AE;Lo;0;L;;;;;N;;;;; +A4F0;LISU LETTER E;Lo;0;L;;;;;N;;;;; +A4F1;LISU LETTER EU;Lo;0;L;;;;;N;;;;; +A4F2;LISU LETTER I;Lo;0;L;;;;;N;;;;; +A4F3;LISU LETTER O;Lo;0;L;;;;;N;;;;; +A4F4;LISU LETTER U;Lo;0;L;;;;;N;;;;; +A4F5;LISU LETTER UE;Lo;0;L;;;;;N;;;;; +A4F6;LISU LETTER UH;Lo;0;L;;;;;N;;;;; +A4F7;LISU LETTER OE;Lo;0;L;;;;;N;;;;; +A4F8;LISU LETTER TONE MYA TI;Lm;0;L;;;;;N;;;;; +A4F9;LISU LETTER TONE NA PO;Lm;0;L;;;;;N;;;;; +A4FA;LISU LETTER TONE MYA CYA;Lm;0;L;;;;;N;;;;; +A4FB;LISU LETTER TONE MYA BO;Lm;0;L;;;;;N;;;;; +A4FC;LISU LETTER TONE MYA NA;Lm;0;L;;;;;N;;;;; +A4FD;LISU LETTER TONE MYA JEU;Lm;0;L;;;;;N;;;;; +A4FE;LISU PUNCTUATION COMMA;Po;0;L;;;;;N;;;;; +A4FF;LISU PUNCTUATION FULL STOP;Po;0;L;;;;;N;;;;; A500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;; A501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;; A502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;; @@ -12635,6 +13118,94 @@ A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695; A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694 A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697; A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696 +A6A0;BAMUM LETTER A;Lo;0;L;;;;;N;;;;; +A6A1;BAMUM LETTER KA;Lo;0;L;;;;;N;;;;; +A6A2;BAMUM LETTER U;Lo;0;L;;;;;N;;;;; +A6A3;BAMUM LETTER KU;Lo;0;L;;;;;N;;;;; +A6A4;BAMUM LETTER EE;Lo;0;L;;;;;N;;;;; +A6A5;BAMUM LETTER REE;Lo;0;L;;;;;N;;;;; +A6A6;BAMUM LETTER TAE;Lo;0;L;;;;;N;;;;; +A6A7;BAMUM LETTER O;Lo;0;L;;;;;N;;;;; +A6A8;BAMUM LETTER NYI;Lo;0;L;;;;;N;;;;; +A6A9;BAMUM LETTER I;Lo;0;L;;;;;N;;;;; +A6AA;BAMUM LETTER LA;Lo;0;L;;;;;N;;;;; +A6AB;BAMUM LETTER PA;Lo;0;L;;;;;N;;;;; +A6AC;BAMUM LETTER RII;Lo;0;L;;;;;N;;;;; +A6AD;BAMUM LETTER RIEE;Lo;0;L;;;;;N;;;;; +A6AE;BAMUM LETTER LEEEE;Lo;0;L;;;;;N;;;;; +A6AF;BAMUM LETTER MEEEE;Lo;0;L;;;;;N;;;;; +A6B0;BAMUM LETTER TAA;Lo;0;L;;;;;N;;;;; +A6B1;BAMUM LETTER NDAA;Lo;0;L;;;;;N;;;;; +A6B2;BAMUM LETTER NJAEM;Lo;0;L;;;;;N;;;;; +A6B3;BAMUM LETTER M;Lo;0;L;;;;;N;;;;; +A6B4;BAMUM LETTER SUU;Lo;0;L;;;;;N;;;;; +A6B5;BAMUM LETTER MU;Lo;0;L;;;;;N;;;;; +A6B6;BAMUM LETTER SHII;Lo;0;L;;;;;N;;;;; +A6B7;BAMUM LETTER SI;Lo;0;L;;;;;N;;;;; +A6B8;BAMUM LETTER SHEUX;Lo;0;L;;;;;N;;;;; +A6B9;BAMUM LETTER SEUX;Lo;0;L;;;;;N;;;;; +A6BA;BAMUM LETTER KYEE;Lo;0;L;;;;;N;;;;; +A6BB;BAMUM LETTER KET;Lo;0;L;;;;;N;;;;; +A6BC;BAMUM LETTER NUAE;Lo;0;L;;;;;N;;;;; +A6BD;BAMUM LETTER NU;Lo;0;L;;;;;N;;;;; +A6BE;BAMUM LETTER NJUAE;Lo;0;L;;;;;N;;;;; +A6BF;BAMUM LETTER YOQ;Lo;0;L;;;;;N;;;;; +A6C0;BAMUM LETTER SHU;Lo;0;L;;;;;N;;;;; +A6C1;BAMUM LETTER YUQ;Lo;0;L;;;;;N;;;;; +A6C2;BAMUM LETTER YA;Lo;0;L;;;;;N;;;;; +A6C3;BAMUM LETTER NSHA;Lo;0;L;;;;;N;;;;; +A6C4;BAMUM LETTER KEUX;Lo;0;L;;;;;N;;;;; +A6C5;BAMUM LETTER PEUX;Lo;0;L;;;;;N;;;;; +A6C6;BAMUM LETTER NJEE;Lo;0;L;;;;;N;;;;; +A6C7;BAMUM LETTER NTEE;Lo;0;L;;;;;N;;;;; +A6C8;BAMUM LETTER PUE;Lo;0;L;;;;;N;;;;; +A6C9;BAMUM LETTER WUE;Lo;0;L;;;;;N;;;;; +A6CA;BAMUM LETTER PEE;Lo;0;L;;;;;N;;;;; +A6CB;BAMUM LETTER FEE;Lo;0;L;;;;;N;;;;; +A6CC;BAMUM LETTER RU;Lo;0;L;;;;;N;;;;; +A6CD;BAMUM LETTER LU;Lo;0;L;;;;;N;;;;; +A6CE;BAMUM LETTER MI;Lo;0;L;;;;;N;;;;; +A6CF;BAMUM LETTER NI;Lo;0;L;;;;;N;;;;; +A6D0;BAMUM LETTER REUX;Lo;0;L;;;;;N;;;;; +A6D1;BAMUM LETTER RAE;Lo;0;L;;;;;N;;;;; +A6D2;BAMUM LETTER KEN;Lo;0;L;;;;;N;;;;; +A6D3;BAMUM LETTER NGKWAEN;Lo;0;L;;;;;N;;;;; +A6D4;BAMUM LETTER NGGA;Lo;0;L;;;;;N;;;;; +A6D5;BAMUM LETTER NGA;Lo;0;L;;;;;N;;;;; +A6D6;BAMUM LETTER SHO;Lo;0;L;;;;;N;;;;; +A6D7;BAMUM LETTER PUAE;Lo;0;L;;;;;N;;;;; +A6D8;BAMUM LETTER FU;Lo;0;L;;;;;N;;;;; +A6D9;BAMUM LETTER FOM;Lo;0;L;;;;;N;;;;; +A6DA;BAMUM LETTER WA;Lo;0;L;;;;;N;;;;; +A6DB;BAMUM LETTER NA;Lo;0;L;;;;;N;;;;; +A6DC;BAMUM LETTER LI;Lo;0;L;;;;;N;;;;; +A6DD;BAMUM LETTER PI;Lo;0;L;;;;;N;;;;; +A6DE;BAMUM LETTER LOQ;Lo;0;L;;;;;N;;;;; +A6DF;BAMUM LETTER KO;Lo;0;L;;;;;N;;;;; +A6E0;BAMUM LETTER MBEN;Lo;0;L;;;;;N;;;;; +A6E1;BAMUM LETTER REN;Lo;0;L;;;;;N;;;;; +A6E2;BAMUM LETTER MEN;Lo;0;L;;;;;N;;;;; +A6E3;BAMUM LETTER MA;Lo;0;L;;;;;N;;;;; +A6E4;BAMUM LETTER TI;Lo;0;L;;;;;N;;;;; +A6E5;BAMUM LETTER KI;Lo;0;L;;;;;N;;;;; +A6E6;BAMUM LETTER MO;Nl;0;L;;;;1;N;;;;; +A6E7;BAMUM LETTER MBAA;Nl;0;L;;;;2;N;;;;; +A6E8;BAMUM LETTER TET;Nl;0;L;;;;3;N;;;;; +A6E9;BAMUM LETTER KPA;Nl;0;L;;;;4;N;;;;; +A6EA;BAMUM LETTER TEN;Nl;0;L;;;;5;N;;;;; +A6EB;BAMUM LETTER NTUU;Nl;0;L;;;;6;N;;;;; +A6EC;BAMUM LETTER SAMBA;Nl;0;L;;;;7;N;;;;; +A6ED;BAMUM LETTER FAAMAE;Nl;0;L;;;;8;N;;;;; +A6EE;BAMUM LETTER KOVUU;Nl;0;L;;;;9;N;;;;; +A6EF;BAMUM LETTER KOGHOM;Nl;0;L;;;;0;N;;;;; +A6F0;BAMUM COMBINING MARK KOQNDON;Mn;230;NSM;;;;;N;;;;; +A6F1;BAMUM COMBINING MARK TUKWENTIS;Mn;230;NSM;;;;;N;;;;; +A6F2;BAMUM NJAEMLI;Po;0;L;;;;;N;;;;; +A6F3;BAMUM FULL STOP;Po;0;L;;;;;N;;;;; +A6F4;BAMUM COLON;Po;0;L;;;;;N;;;;; +A6F5;BAMUM COMMA;Po;0;L;;;;;N;;;;; +A6F6;BAMUM SEMICOLON;Po;0;L;;;;;N;;;;; +A6F7;BAMUM QUESTION MARK;Po;0;L;;;;;N;;;;; A700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;; A701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;; A702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;; @@ -12825,6 +13396,16 @@ A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;; A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;; A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;; A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;; +A830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +A831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; +A832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +A833;NORTH INDIC FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;; +A834;NORTH INDIC FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +A835;NORTH INDIC FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +A836;NORTH INDIC QUARTER MARK;So;0;L;;;;;N;;;;; +A837;NORTH INDIC PLACEHOLDER MARK;So;0;L;;;;;N;;;;; +A838;NORTH INDIC RUPEE MARK;Sc;0;ET;;;;;N;;;;; +A839;NORTH INDIC QUANTITY MARK;So;0;ET;;;;;N;;;;; A840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;; A841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;; A842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;; @@ -12962,6 +13543,34 @@ A8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; A8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; A8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; A8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A8E0;COMBINING DEVANAGARI DIGIT ZERO;Mn;230;NSM;;;;;N;;;;; +A8E1;COMBINING DEVANAGARI DIGIT ONE;Mn;230;NSM;;;;;N;;;;; +A8E2;COMBINING DEVANAGARI DIGIT TWO;Mn;230;NSM;;;;;N;;;;; +A8E3;COMBINING DEVANAGARI DIGIT THREE;Mn;230;NSM;;;;;N;;;;; +A8E4;COMBINING DEVANAGARI DIGIT FOUR;Mn;230;NSM;;;;;N;;;;; +A8E5;COMBINING DEVANAGARI DIGIT FIVE;Mn;230;NSM;;;;;N;;;;; +A8E6;COMBINING DEVANAGARI DIGIT SIX;Mn;230;NSM;;;;;N;;;;; +A8E7;COMBINING DEVANAGARI DIGIT SEVEN;Mn;230;NSM;;;;;N;;;;; +A8E8;COMBINING DEVANAGARI DIGIT EIGHT;Mn;230;NSM;;;;;N;;;;; +A8E9;COMBINING DEVANAGARI DIGIT NINE;Mn;230;NSM;;;;;N;;;;; +A8EA;COMBINING DEVANAGARI LETTER A;Mn;230;NSM;;;;;N;;;;; +A8EB;COMBINING DEVANAGARI LETTER U;Mn;230;NSM;;;;;N;;;;; +A8EC;COMBINING DEVANAGARI LETTER KA;Mn;230;NSM;;;;;N;;;;; +A8ED;COMBINING DEVANAGARI LETTER NA;Mn;230;NSM;;;;;N;;;;; +A8EE;COMBINING DEVANAGARI LETTER PA;Mn;230;NSM;;;;;N;;;;; +A8EF;COMBINING DEVANAGARI LETTER RA;Mn;230;NSM;;;;;N;;;;; +A8F0;COMBINING DEVANAGARI LETTER VI;Mn;230;NSM;;;;;N;;;;; +A8F1;COMBINING DEVANAGARI SIGN AVAGRAHA;Mn;230;NSM;;;;;N;;;;; +A8F2;DEVANAGARI SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;; +A8F3;DEVANAGARI SIGN CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;; +A8F4;DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;; +A8F5;DEVANAGARI SIGN CANDRABINDU TWO;Lo;0;L;;;;;N;;;;; +A8F6;DEVANAGARI SIGN CANDRABINDU THREE;Lo;0;L;;;;;N;;;;; +A8F7;DEVANAGARI SIGN CANDRABINDU AVAGRAHA;Lo;0;L;;;;;N;;;;; +A8F8;DEVANAGARI SIGN PUSHPIKA;Po;0;L;;;;;N;;;;; +A8F9;DEVANAGARI GAP FILLER;Po;0;L;;;;;N;;;;; +A8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;; +A8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;; A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -13047,6 +13656,126 @@ A951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; A952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;; A953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;; A95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;; +A960;HANGUL CHOSEONG TIKEUT-MIEUM;Lo;0;L;;;;;N;;;;; +A961;HANGUL CHOSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +A962;HANGUL CHOSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;; +A963;HANGUL CHOSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;; +A964;HANGUL CHOSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;; +A965;HANGUL CHOSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +A966;HANGUL CHOSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; +A967;HANGUL CHOSEONG RIEUL-SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +A968;HANGUL CHOSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;; +A969;HANGUL CHOSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;; +A96A;HANGUL CHOSEONG RIEUL-SSANGPIEUP;Lo;0;L;;;;;N;;;;; +A96B;HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +A96C;HANGUL CHOSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;; +A96D;HANGUL CHOSEONG RIEUL-CIEUC;Lo;0;L;;;;;N;;;;; +A96E;HANGUL CHOSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +A96F;HANGUL CHOSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +A970;HANGUL CHOSEONG MIEUM-TIKEUT;Lo;0;L;;;;;N;;;;; +A971;HANGUL CHOSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +A972;HANGUL CHOSEONG PIEUP-SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +A973;HANGUL CHOSEONG PIEUP-KHIEUKH;Lo;0;L;;;;;N;;;;; +A974;HANGUL CHOSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +A975;HANGUL CHOSEONG SSANGSIOS-PIEUP;Lo;0;L;;;;;N;;;;; +A976;HANGUL CHOSEONG IEUNG-RIEUL;Lo;0;L;;;;;N;;;;; +A977;HANGUL CHOSEONG IEUNG-HIEUH;Lo;0;L;;;;;N;;;;; +A978;HANGUL CHOSEONG SSANGCIEUC-HIEUH;Lo;0;L;;;;;N;;;;; +A979;HANGUL CHOSEONG SSANGTHIEUTH;Lo;0;L;;;;;N;;;;; +A97A;HANGUL CHOSEONG PHIEUPH-HIEUH;Lo;0;L;;;;;N;;;;; +A97B;HANGUL CHOSEONG HIEUH-SIOS;Lo;0;L;;;;;N;;;;; +A97C;HANGUL CHOSEONG SSANGYEORINHIEUH;Lo;0;L;;;;;N;;;;; +A980;JAVANESE SIGN PANYANGGA;Mn;0;NSM;;;;;N;;;;; +A981;JAVANESE SIGN CECAK;Mn;0;NSM;;;;;N;;;;; +A982;JAVANESE SIGN LAYAR;Mn;0;NSM;;;;;N;;;;; +A983;JAVANESE SIGN WIGNYAN;Mc;0;L;;;;;N;;;;; +A984;JAVANESE LETTER A;Lo;0;L;;;;;N;;;;; +A985;JAVANESE LETTER I KAWI;Lo;0;L;;;;;N;;;;; +A986;JAVANESE LETTER I;Lo;0;L;;;;;N;;;;; +A987;JAVANESE LETTER II;Lo;0;L;;;;;N;;;;; +A988;JAVANESE LETTER U;Lo;0;L;;;;;N;;;;; +A989;JAVANESE LETTER PA CEREK;Lo;0;L;;;;;N;;;;; +A98A;JAVANESE LETTER NGA LELET;Lo;0;L;;;;;N;;;;; +A98B;JAVANESE LETTER NGA LELET RASWADI;Lo;0;L;;;;;N;;;;; +A98C;JAVANESE LETTER E;Lo;0;L;;;;;N;;;;; +A98D;JAVANESE LETTER AI;Lo;0;L;;;;;N;;;;; +A98E;JAVANESE LETTER O;Lo;0;L;;;;;N;;;;; +A98F;JAVANESE LETTER KA;Lo;0;L;;;;;N;;;;; +A990;JAVANESE LETTER KA SASAK;Lo;0;L;;;;;N;;;;; +A991;JAVANESE LETTER KA MURDA;Lo;0;L;;;;;N;;;;; +A992;JAVANESE LETTER GA;Lo;0;L;;;;;N;;;;; +A993;JAVANESE LETTER GA MURDA;Lo;0;L;;;;;N;;;;; +A994;JAVANESE LETTER NGA;Lo;0;L;;;;;N;;;;; +A995;JAVANESE LETTER CA;Lo;0;L;;;;;N;;;;; +A996;JAVANESE LETTER CA MURDA;Lo;0;L;;;;;N;;;;; +A997;JAVANESE LETTER JA;Lo;0;L;;;;;N;;;;; +A998;JAVANESE LETTER NYA MURDA;Lo;0;L;;;;;N;;;;; +A999;JAVANESE LETTER JA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99A;JAVANESE LETTER NYA;Lo;0;L;;;;;N;;;;; +A99B;JAVANESE LETTER TTA;Lo;0;L;;;;;N;;;;; +A99C;JAVANESE LETTER TTA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99D;JAVANESE LETTER DDA;Lo;0;L;;;;;N;;;;; +A99E;JAVANESE LETTER DDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99F;JAVANESE LETTER NA MURDA;Lo;0;L;;;;;N;;;;; +A9A0;JAVANESE LETTER TA;Lo;0;L;;;;;N;;;;; +A9A1;JAVANESE LETTER TA MURDA;Lo;0;L;;;;;N;;;;; +A9A2;JAVANESE LETTER DA;Lo;0;L;;;;;N;;;;; +A9A3;JAVANESE LETTER DA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A9A4;JAVANESE LETTER NA;Lo;0;L;;;;;N;;;;; +A9A5;JAVANESE LETTER PA;Lo;0;L;;;;;N;;;;; +A9A6;JAVANESE LETTER PA MURDA;Lo;0;L;;;;;N;;;;; +A9A7;JAVANESE LETTER BA;Lo;0;L;;;;;N;;;;; +A9A8;JAVANESE LETTER BA MURDA;Lo;0;L;;;;;N;;;;; +A9A9;JAVANESE LETTER MA;Lo;0;L;;;;;N;;;;; +A9AA;JAVANESE LETTER YA;Lo;0;L;;;;;N;;;;; +A9AB;JAVANESE LETTER RA;Lo;0;L;;;;;N;;;;; +A9AC;JAVANESE LETTER RA AGUNG;Lo;0;L;;;;;N;;;;; +A9AD;JAVANESE LETTER LA;Lo;0;L;;;;;N;;;;; +A9AE;JAVANESE LETTER WA;Lo;0;L;;;;;N;;;;; +A9AF;JAVANESE LETTER SA MURDA;Lo;0;L;;;;;N;;;;; +A9B0;JAVANESE LETTER SA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A9B1;JAVANESE LETTER SA;Lo;0;L;;;;;N;;;;; +A9B2;JAVANESE LETTER HA;Lo;0;L;;;;;N;;;;; +A9B3;JAVANESE SIGN CECAK TELU;Mn;7;NSM;;;;;N;;;;; +A9B4;JAVANESE VOWEL SIGN TARUNG;Mc;0;L;;;;;N;;;;; +A9B5;JAVANESE VOWEL SIGN TOLONG;Mc;0;L;;;;;N;;;;; +A9B6;JAVANESE VOWEL SIGN WULU;Mn;0;NSM;;;;;N;;;;; +A9B7;JAVANESE VOWEL SIGN WULU MELIK;Mn;0;NSM;;;;;N;;;;; +A9B8;JAVANESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;; +A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;; +A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; +A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;; +A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; +A9BD;JAVANESE CONSONANT SIGN KERET;Mc;0;L;;;;;N;;;;; +A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;; +A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;; +A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;; +A9C1;JAVANESE LEFT RERENGGAN;Po;0;L;;;;;N;;;;; +A9C2;JAVANESE RIGHT RERENGGAN;Po;0;L;;;;;N;;;;; +A9C3;JAVANESE PADA ANDAP;Po;0;L;;;;;N;;;;; +A9C4;JAVANESE PADA MADYA;Po;0;L;;;;;N;;;;; +A9C5;JAVANESE PADA LUHUR;Po;0;L;;;;;N;;;;; +A9C6;JAVANESE PADA WINDU;Po;0;L;;;;;N;;;;; +A9C7;JAVANESE PADA PANGKAT;Po;0;L;;;;;N;;;;; +A9C8;JAVANESE PADA LINGSA;Po;0;L;;;;;N;;;;; +A9C9;JAVANESE PADA LUNGSI;Po;0;L;;;;;N;;;;; +A9CA;JAVANESE PADA ADEG;Po;0;L;;;;;N;;;;; +A9CB;JAVANESE PADA ADEG ADEG;Po;0;L;;;;;N;;;;; +A9CC;JAVANESE PADA PISELEH;Po;0;L;;;;;N;;;;; +A9CD;JAVANESE TURNED PADA PISELEH;Po;0;L;;;;;N;;;;; +A9CF;JAVANESE PANGRANGKEP;Lm;0;L;;;;;N;;;;; +A9D0;JAVANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A9D1;JAVANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A9D2;JAVANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A9D3;JAVANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A9D4;JAVANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A9D5;JAVANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A9D6;JAVANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A9D7;JAVANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A9D8;JAVANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A9D9;JAVANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A9DE;JAVANESE PADA TIRTA TUMETES;Po;0;L;;;;;N;;;;; +A9DF;JAVANESE PADA ISEN-ISEN;Po;0;L;;;;;N;;;;; AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;; AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;; AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;; @@ -13130,8 +13859,236 @@ AA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;; AA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;; AA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;; AA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;; +AA60;MYANMAR LETTER KHAMTI GA;Lo;0;L;;;;;N;;;;; +AA61;MYANMAR LETTER KHAMTI CA;Lo;0;L;;;;;N;;;;; +AA62;MYANMAR LETTER KHAMTI CHA;Lo;0;L;;;;;N;;;;; +AA63;MYANMAR LETTER KHAMTI JA;Lo;0;L;;;;;N;;;;; +AA64;MYANMAR LETTER KHAMTI JHA;Lo;0;L;;;;;N;;;;; +AA65;MYANMAR LETTER KHAMTI NYA;Lo;0;L;;;;;N;;;;; +AA66;MYANMAR LETTER KHAMTI TTA;Lo;0;L;;;;;N;;;;; +AA67;MYANMAR LETTER KHAMTI TTHA;Lo;0;L;;;;;N;;;;; +AA68;MYANMAR LETTER KHAMTI DDA;Lo;0;L;;;;;N;;;;; +AA69;MYANMAR LETTER KHAMTI DDHA;Lo;0;L;;;;;N;;;;; +AA6A;MYANMAR LETTER KHAMTI DHA;Lo;0;L;;;;;N;;;;; +AA6B;MYANMAR LETTER KHAMTI NA;Lo;0;L;;;;;N;;;;; +AA6C;MYANMAR LETTER KHAMTI SA;Lo;0;L;;;;;N;;;;; +AA6D;MYANMAR LETTER KHAMTI HA;Lo;0;L;;;;;N;;;;; +AA6E;MYANMAR LETTER KHAMTI HHA;Lo;0;L;;;;;N;;;;; +AA6F;MYANMAR LETTER KHAMTI FA;Lo;0;L;;;;;N;;;;; +AA70;MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION;Lm;0;L;;;;;N;;;;; +AA71;MYANMAR LETTER KHAMTI XA;Lo;0;L;;;;;N;;;;; +AA72;MYANMAR LETTER KHAMTI ZA;Lo;0;L;;;;;N;;;;; +AA73;MYANMAR LETTER KHAMTI RA;Lo;0;L;;;;;N;;;;; +AA74;MYANMAR LOGOGRAM KHAMTI OAY;Lo;0;L;;;;;N;;;;; +AA75;MYANMAR LOGOGRAM KHAMTI QN;Lo;0;L;;;;;N;;;;; +AA76;MYANMAR LOGOGRAM KHAMTI HM;Lo;0;L;;;;;N;;;;; +AA77;MYANMAR SYMBOL AITON EXCLAMATION;So;0;L;;;;;N;;;;; +AA78;MYANMAR SYMBOL AITON ONE;So;0;L;;;;;N;;;;; +AA79;MYANMAR SYMBOL AITON TWO;So;0;L;;;;;N;;;;; +AA7A;MYANMAR LETTER AITON RA;Lo;0;L;;;;;N;;;;; +AA7B;MYANMAR SIGN PAO KAREN TONE;Mc;0;L;;;;;N;;;;; +AA80;TAI VIET LETTER LOW KO;Lo;0;L;;;;;N;;;;; +AA81;TAI VIET LETTER HIGH KO;Lo;0;L;;;;;N;;;;; +AA82;TAI VIET LETTER LOW KHO;Lo;0;L;;;;;N;;;;; +AA83;TAI VIET LETTER HIGH KHO;Lo;0;L;;;;;N;;;;; +AA84;TAI VIET LETTER LOW KHHO;Lo;0;L;;;;;N;;;;; +AA85;TAI VIET LETTER HIGH KHHO;Lo;0;L;;;;;N;;;;; +AA86;TAI VIET LETTER LOW GO;Lo;0;L;;;;;N;;;;; +AA87;TAI VIET LETTER HIGH GO;Lo;0;L;;;;;N;;;;; +AA88;TAI VIET LETTER LOW NGO;Lo;0;L;;;;;N;;;;; +AA89;TAI VIET LETTER HIGH NGO;Lo;0;L;;;;;N;;;;; +AA8A;TAI VIET LETTER LOW CO;Lo;0;L;;;;;N;;;;; +AA8B;TAI VIET LETTER HIGH CO;Lo;0;L;;;;;N;;;;; +AA8C;TAI VIET LETTER LOW CHO;Lo;0;L;;;;;N;;;;; +AA8D;TAI VIET LETTER HIGH CHO;Lo;0;L;;;;;N;;;;; +AA8E;TAI VIET LETTER LOW SO;Lo;0;L;;;;;N;;;;; +AA8F;TAI VIET LETTER HIGH SO;Lo;0;L;;;;;N;;;;; +AA90;TAI VIET LETTER LOW NYO;Lo;0;L;;;;;N;;;;; +AA91;TAI VIET LETTER HIGH NYO;Lo;0;L;;;;;N;;;;; +AA92;TAI VIET LETTER LOW DO;Lo;0;L;;;;;N;;;;; +AA93;TAI VIET LETTER HIGH DO;Lo;0;L;;;;;N;;;;; +AA94;TAI VIET LETTER LOW TO;Lo;0;L;;;;;N;;;;; +AA95;TAI VIET LETTER HIGH TO;Lo;0;L;;;;;N;;;;; +AA96;TAI VIET LETTER LOW THO;Lo;0;L;;;;;N;;;;; +AA97;TAI VIET LETTER HIGH THO;Lo;0;L;;;;;N;;;;; +AA98;TAI VIET LETTER LOW NO;Lo;0;L;;;;;N;;;;; +AA99;TAI VIET LETTER HIGH NO;Lo;0;L;;;;;N;;;;; +AA9A;TAI VIET LETTER LOW BO;Lo;0;L;;;;;N;;;;; +AA9B;TAI VIET LETTER HIGH BO;Lo;0;L;;;;;N;;;;; +AA9C;TAI VIET LETTER LOW PO;Lo;0;L;;;;;N;;;;; +AA9D;TAI VIET LETTER HIGH PO;Lo;0;L;;;;;N;;;;; +AA9E;TAI VIET LETTER LOW PHO;Lo;0;L;;;;;N;;;;; +AA9F;TAI VIET LETTER HIGH PHO;Lo;0;L;;;;;N;;;;; +AAA0;TAI VIET LETTER LOW FO;Lo;0;L;;;;;N;;;;; +AAA1;TAI VIET LETTER HIGH FO;Lo;0;L;;;;;N;;;;; +AAA2;TAI VIET LETTER LOW MO;Lo;0;L;;;;;N;;;;; +AAA3;TAI VIET LETTER HIGH MO;Lo;0;L;;;;;N;;;;; +AAA4;TAI VIET LETTER LOW YO;Lo;0;L;;;;;N;;;;; +AAA5;TAI VIET LETTER HIGH YO;Lo;0;L;;;;;N;;;;; +AAA6;TAI VIET LETTER LOW RO;Lo;0;L;;;;;N;;;;; +AAA7;TAI VIET LETTER HIGH RO;Lo;0;L;;;;;N;;;;; +AAA8;TAI VIET LETTER LOW LO;Lo;0;L;;;;;N;;;;; +AAA9;TAI VIET LETTER HIGH LO;Lo;0;L;;;;;N;;;;; +AAAA;TAI VIET LETTER LOW VO;Lo;0;L;;;;;N;;;;; +AAAB;TAI VIET LETTER HIGH VO;Lo;0;L;;;;;N;;;;; +AAAC;TAI VIET LETTER LOW HO;Lo;0;L;;;;;N;;;;; +AAAD;TAI VIET LETTER HIGH HO;Lo;0;L;;;;;N;;;;; +AAAE;TAI VIET LETTER LOW O;Lo;0;L;;;;;N;;;;; +AAAF;TAI VIET LETTER HIGH O;Lo;0;L;;;;;N;;;;; +AAB0;TAI VIET MAI KANG;Mn;230;NSM;;;;;N;;;;; +AAB1;TAI VIET VOWEL AA;Lo;0;L;;;;;N;;;;; +AAB2;TAI VIET VOWEL I;Mn;230;NSM;;;;;N;;;;; +AAB3;TAI VIET VOWEL UE;Mn;230;NSM;;;;;N;;;;; +AAB4;TAI VIET VOWEL U;Mn;220;NSM;;;;;N;;;;; +AAB5;TAI VIET VOWEL E;Lo;0;L;;;;;N;;;;; +AAB6;TAI VIET VOWEL O;Lo;0;L;;;;;N;;;;; +AAB7;TAI VIET MAI KHIT;Mn;230;NSM;;;;;N;;;;; +AAB8;TAI VIET VOWEL IA;Mn;230;NSM;;;;;N;;;;; +AAB9;TAI VIET VOWEL UEA;Lo;0;L;;;;;N;;;;; +AABA;TAI VIET VOWEL UA;Lo;0;L;;;;;N;;;;; +AABB;TAI VIET VOWEL AUE;Lo;0;L;;;;;N;;;;; +AABC;TAI VIET VOWEL AY;Lo;0;L;;;;;N;;;;; +AABD;TAI VIET VOWEL AN;Lo;0;L;;;;;N;;;;; +AABE;TAI VIET VOWEL AM;Mn;230;NSM;;;;;N;;;;; +AABF;TAI VIET TONE MAI EK;Mn;230;NSM;;;;;N;;;;; +AAC0;TAI VIET TONE MAI NUENG;Lo;0;L;;;;;N;;;;; +AAC1;TAI VIET TONE MAI THO;Mn;230;NSM;;;;;N;;;;; +AAC2;TAI VIET TONE MAI SONG;Lo;0;L;;;;;N;;;;; +AADB;TAI VIET SYMBOL KON;Lo;0;L;;;;;N;;;;; +AADC;TAI VIET SYMBOL NUENG;Lo;0;L;;;;;N;;;;; +AADD;TAI VIET SYMBOL SAM;Lm;0;L;;;;;N;;;;; +AADE;TAI VIET SYMBOL HO HOI;Po;0;L;;;;;N;;;;; +AADF;TAI VIET SYMBOL KOI KOI;Po;0;L;;;;;N;;;;; +ABC0;MEETEI MAYEK LETTER KOK;Lo;0;L;;;;;N;;;;; +ABC1;MEETEI MAYEK LETTER SAM;Lo;0;L;;;;;N;;;;; +ABC2;MEETEI MAYEK LETTER LAI;Lo;0;L;;;;;N;;;;; +ABC3;MEETEI MAYEK LETTER MIT;Lo;0;L;;;;;N;;;;; +ABC4;MEETEI MAYEK LETTER PA;Lo;0;L;;;;;N;;;;; +ABC5;MEETEI MAYEK LETTER NA;Lo;0;L;;;;;N;;;;; +ABC6;MEETEI MAYEK LETTER CHIL;Lo;0;L;;;;;N;;;;; +ABC7;MEETEI MAYEK LETTER TIL;Lo;0;L;;;;;N;;;;; +ABC8;MEETEI MAYEK LETTER KHOU;Lo;0;L;;;;;N;;;;; +ABC9;MEETEI MAYEK LETTER NGOU;Lo;0;L;;;;;N;;;;; +ABCA;MEETEI MAYEK LETTER THOU;Lo;0;L;;;;;N;;;;; +ABCB;MEETEI MAYEK LETTER WAI;Lo;0;L;;;;;N;;;;; +ABCC;MEETEI MAYEK LETTER YANG;Lo;0;L;;;;;N;;;;; +ABCD;MEETEI MAYEK LETTER HUK;Lo;0;L;;;;;N;;;;; +ABCE;MEETEI MAYEK LETTER UN;Lo;0;L;;;;;N;;;;; +ABCF;MEETEI MAYEK LETTER I;Lo;0;L;;;;;N;;;;; +ABD0;MEETEI MAYEK LETTER PHAM;Lo;0;L;;;;;N;;;;; +ABD1;MEETEI MAYEK LETTER ATIYA;Lo;0;L;;;;;N;;;;; +ABD2;MEETEI MAYEK LETTER GOK;Lo;0;L;;;;;N;;;;; +ABD3;MEETEI MAYEK LETTER JHAM;Lo;0;L;;;;;N;;;;; +ABD4;MEETEI MAYEK LETTER RAI;Lo;0;L;;;;;N;;;;; +ABD5;MEETEI MAYEK LETTER BA;Lo;0;L;;;;;N;;;;; +ABD6;MEETEI MAYEK LETTER JIL;Lo;0;L;;;;;N;;;;; +ABD7;MEETEI MAYEK LETTER DIL;Lo;0;L;;;;;N;;;;; +ABD8;MEETEI MAYEK LETTER GHOU;Lo;0;L;;;;;N;;;;; +ABD9;MEETEI MAYEK LETTER DHOU;Lo;0;L;;;;;N;;;;; +ABDA;MEETEI MAYEK LETTER BHAM;Lo;0;L;;;;;N;;;;; +ABDB;MEETEI MAYEK LETTER KOK LONSUM;Lo;0;L;;;;;N;;;;; +ABDC;MEETEI MAYEK LETTER LAI LONSUM;Lo;0;L;;;;;N;;;;; +ABDD;MEETEI MAYEK LETTER MIT LONSUM;Lo;0;L;;;;;N;;;;; +ABDE;MEETEI MAYEK LETTER PA LONSUM;Lo;0;L;;;;;N;;;;; +ABDF;MEETEI MAYEK LETTER NA LONSUM;Lo;0;L;;;;;N;;;;; +ABE0;MEETEI MAYEK LETTER TIL LONSUM;Lo;0;L;;;;;N;;;;; +ABE1;MEETEI MAYEK LETTER NGOU LONSUM;Lo;0;L;;;;;N;;;;; +ABE2;MEETEI MAYEK LETTER I LONSUM;Lo;0;L;;;;;N;;;;; +ABE3;MEETEI MAYEK VOWEL SIGN ONAP;Mc;0;L;;;;;N;;;;; +ABE4;MEETEI MAYEK VOWEL SIGN INAP;Mc;0;L;;;;;N;;;;; +ABE5;MEETEI MAYEK VOWEL SIGN ANAP;Mn;0;NSM;;;;;N;;;;; +ABE6;MEETEI MAYEK VOWEL SIGN YENAP;Mc;0;L;;;;;N;;;;; +ABE7;MEETEI MAYEK VOWEL SIGN SOUNAP;Mc;0;L;;;;;N;;;;; +ABE8;MEETEI MAYEK VOWEL SIGN UNAP;Mn;0;NSM;;;;;N;;;;; +ABE9;MEETEI MAYEK VOWEL SIGN CHEINAP;Mc;0;L;;;;;N;;;;; +ABEA;MEETEI MAYEK VOWEL SIGN NUNG;Mc;0;L;;;;;N;;;;; +ABEB;MEETEI MAYEK CHEIKHEI;Po;0;L;;;;;N;;;;; +ABEC;MEETEI MAYEK LUM IYEK;Mc;0;L;;;;;N;;;;; +ABED;MEETEI MAYEK APUN IYEK;Mn;9;NSM;;;;;N;;;;; +ABF0;MEETEI MAYEK DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +ABF1;MEETEI MAYEK DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +ABF2;MEETEI MAYEK DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +ABF3;MEETEI MAYEK DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +ABF4;MEETEI MAYEK DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +ABF5;MEETEI MAYEK DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +ABF6;MEETEI MAYEK DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +ABF7;MEETEI MAYEK DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +ABF8;MEETEI MAYEK DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +ABF9;MEETEI MAYEK DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; AC00;;Lo;0;L;;;;;N;;;;; D7A3;;Lo;0;L;;;;;N;;;;; +D7B0;HANGUL JUNGSEONG O-YEO;Lo;0;L;;;;;N;;;;; +D7B1;HANGUL JUNGSEONG O-O-I;Lo;0;L;;;;;N;;;;; +D7B2;HANGUL JUNGSEONG YO-A;Lo;0;L;;;;;N;;;;; +D7B3;HANGUL JUNGSEONG YO-AE;Lo;0;L;;;;;N;;;;; +D7B4;HANGUL JUNGSEONG YO-EO;Lo;0;L;;;;;N;;;;; +D7B5;HANGUL JUNGSEONG U-YEO;Lo;0;L;;;;;N;;;;; +D7B6;HANGUL JUNGSEONG U-I-I;Lo;0;L;;;;;N;;;;; +D7B7;HANGUL JUNGSEONG YU-AE;Lo;0;L;;;;;N;;;;; +D7B8;HANGUL JUNGSEONG YU-O;Lo;0;L;;;;;N;;;;; +D7B9;HANGUL JUNGSEONG EU-A;Lo;0;L;;;;;N;;;;; +D7BA;HANGUL JUNGSEONG EU-EO;Lo;0;L;;;;;N;;;;; +D7BB;HANGUL JUNGSEONG EU-E;Lo;0;L;;;;;N;;;;; +D7BC;HANGUL JUNGSEONG EU-O;Lo;0;L;;;;;N;;;;; +D7BD;HANGUL JUNGSEONG I-YA-O;Lo;0;L;;;;;N;;;;; +D7BE;HANGUL JUNGSEONG I-YAE;Lo;0;L;;;;;N;;;;; +D7BF;HANGUL JUNGSEONG I-YEO;Lo;0;L;;;;;N;;;;; +D7C0;HANGUL JUNGSEONG I-YE;Lo;0;L;;;;;N;;;;; +D7C1;HANGUL JUNGSEONG I-O-I;Lo;0;L;;;;;N;;;;; +D7C2;HANGUL JUNGSEONG I-YO;Lo;0;L;;;;;N;;;;; +D7C3;HANGUL JUNGSEONG I-YU;Lo;0;L;;;;;N;;;;; +D7C4;HANGUL JUNGSEONG I-I;Lo;0;L;;;;;N;;;;; +D7C5;HANGUL JUNGSEONG ARAEA-A;Lo;0;L;;;;;N;;;;; +D7C6;HANGUL JUNGSEONG ARAEA-E;Lo;0;L;;;;;N;;;;; +D7CB;HANGUL JONGSEONG NIEUN-RIEUL;Lo;0;L;;;;;N;;;;; +D7CC;HANGUL JONGSEONG NIEUN-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7CD;HANGUL JONGSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +D7CE;HANGUL JONGSEONG SSANGTIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +D7CF;HANGUL JONGSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +D7D0;HANGUL JONGSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;; +D7D1;HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +D7D2;HANGUL JONGSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;; +D7D3;HANGUL JONGSEONG TIKEUT-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7D4;HANGUL JONGSEONG TIKEUT-THIEUTH;Lo;0;L;;;;;N;;;;; +D7D5;HANGUL JONGSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +D7D6;HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;; +D7D7;HANGUL JONGSEONG SSANGRIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +D7D8;HANGUL JONGSEONG RIEUL-MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; +D7D9;HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +D7DA;HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +D7DB;HANGUL JONGSEONG RIEUL-YESIEUNG;Lo;0;L;;;;;N;;;;; +D7DC;HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH;Lo;0;L;;;;;N;;;;; +D7DD;HANGUL JONGSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; +D7DE;HANGUL JONGSEONG MIEUM-NIEUN;Lo;0;L;;;;;N;;;;; +D7DF;HANGUL JONGSEONG MIEUM-SSANGNIEUN;Lo;0;L;;;;;N;;;;; +D7E0;HANGUL JONGSEONG SSANGMIEUM;Lo;0;L;;;;;N;;;;; +D7E1;HANGUL JONGSEONG MIEUM-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +D7E2;HANGUL JONGSEONG MIEUM-CIEUC;Lo;0;L;;;;;N;;;;; +D7E3;HANGUL JONGSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +D7E4;HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;; +D7E5;HANGUL JONGSEONG PIEUP-MIEUM;Lo;0;L;;;;;N;;;;; +D7E6;HANGUL JONGSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;; +D7E7;HANGUL JONGSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +D7E8;HANGUL JONGSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; +D7E9;HANGUL JONGSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7EA;HANGUL JONGSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; +D7EB;HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +D7EC;HANGUL JONGSEONG SSANGSIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +D7ED;HANGUL JONGSEONG SSANGSIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +D7EE;HANGUL JONGSEONG SIOS-PANSIOS;Lo;0;L;;;;;N;;;;; +D7EF;HANGUL JONGSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +D7F0;HANGUL JONGSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7F1;HANGUL JONGSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +D7F2;HANGUL JONGSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; +D7F3;HANGUL JONGSEONG PANSIOS-PIEUP;Lo;0;L;;;;;N;;;;; +D7F4;HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +D7F5;HANGUL JONGSEONG YESIEUNG-MIEUM;Lo;0;L;;;;;N;;;;; +D7F6;HANGUL JONGSEONG YESIEUNG-HIEUH;Lo;0;L;;;;;N;;;;; +D7F7;HANGUL JONGSEONG CIEUC-PIEUP;Lo;0;L;;;;;N;;;;; +D7F8;HANGUL JONGSEONG CIEUC-SSANGPIEUP;Lo;0;L;;;;;N;;;;; +D7F9;HANGUL JONGSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;; +D7FA;HANGUL JONGSEONG PHIEUPH-SIOS;Lo;0;L;;;;;N;;;;; +D7FB;HANGUL JONGSEONG PHIEUPH-THIEUTH;Lo;0;L;;;;;N;;;;; D800;;Cs;0;L;;;;;N;;;;; DB7F;;Cs;0;L;;;;;N;;;;; DB80;;Cs;0;L;;;;;N;;;;; @@ -13427,11 +14384,11 @@ FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;; FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;; FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;; FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;; -FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;*;;; +FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;;;; FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;; FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;; FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;; -FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;*;;; +FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;;;; FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;; FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;; FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;; @@ -13501,6 +14458,9 @@ FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;; FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;; FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;; FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;; +FA6B;CJK COMPATIBILITY IDEOGRAPH-FA6B;Lo;0;L;6075;;;;N;;;;; +FA6C;CJK COMPATIBILITY IDEOGRAPH-FA6C;Lo;0;L;242EE;;;;N;;;;; +FA6D;CJK COMPATIBILITY IDEOGRAPH-FA6D;Lo;0;L;8218;;;;N;;;;; FA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;; FA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;; FA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;; @@ -14586,8 +15546,8 @@ FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;FULLWIDTH OPENING CUR FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON; 007C;;;;N;FULLWIDTH VERTICAL BAR;;;; FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;; FF5E;FULLWIDTH TILDE;Sm;0;ON; 007E;;;;N;FULLWIDTH SPACING TILDE;;;; -FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON; 2985;;;;Y;;*;;; -FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON; 2986;;;;Y;;*;;; +FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON; 2985;;;;Y;;;;; +FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON; 2986;;;;Y;;;;; FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;; FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;; FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;; @@ -14649,8 +15609,8 @@ FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L; 30EC;;;;N;;;;; FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L; 30ED;;;;N;;;;; FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L; 30EF;;;;N;;;;; FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L; 30F3;;;;N;;;;; -FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L; 3099;;;;N;;halfwidth katakana-hiragana voiced sound mark;;; -FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L; 309A;;;;N;;halfwidth katakana-hiragana semi-voiced sound mark;;; +FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L; 3099;;;;N;;;;; +FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L; 309A;;;;N;;;;; FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L; 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;; FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L; 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;; FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L; 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;; @@ -14706,7 +15666,7 @@ FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L; 3163;;;;N;;;;; FFE0;FULLWIDTH CENT SIGN;Sc;0;ET; 00A2;;;;N;;;;; FFE1;FULLWIDTH POUND SIGN;Sc;0;ET; 00A3;;;;N;;;;; FFE2;FULLWIDTH NOT SIGN;Sm;0;ON; 00AC;;;;N;;;;; -FFE3;FULLWIDTH MACRON;Sk;0;ON; 00AF;;;;N;FULLWIDTH SPACING MACRON;*;;; +FFE3;FULLWIDTH MACRON;Sk;0;ON; 00AF;;;;N;FULLWIDTH SPACING MACRON;;;; FFE4;FULLWIDTH BROKEN BAR;So;0;ON; 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;; FFE5;FULLWIDTH YEN SIGN;Sc;0;ET; 00A5;;;;N;;;;; FFE6;FULLWIDTH WON SIGN;Sc;0;ET; 20A9;;;;N;;;;; @@ -14883,9 +15843,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;; 100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;; 100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;; -100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;pug;;; +100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;;;; 100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;; -100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;gup;;; +100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;;;; 100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;; 100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;; 100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;; @@ -15216,7 +16176,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;; 1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;; 1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;; -1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;Faliscan;;; +1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;;;; 10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;; 10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;; 10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;; @@ -15224,14 +16184,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;; 10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;; 10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;; -10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;Faliscan;;; +10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;;;; 10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;; 10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;; 1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;; -1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;Umbrian;;; -1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;Umbrian;;; -1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;Oscan;;; -1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;Oscan;;; +1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;;;; +1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;;;; +1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;;;; +1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;;;; 10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;; 10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;; 10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;; @@ -15567,6 +16527,37 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;; 1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;; 1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;; +10840;IMPERIAL ARAMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10841;IMPERIAL ARAMAIC LETTER BETH;Lo;0;R;;;;;N;;;;; +10842;IMPERIAL ARAMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10843;IMPERIAL ARAMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;; +10844;IMPERIAL ARAMAIC LETTER HE;Lo;0;R;;;;;N;;;;; +10845;IMPERIAL ARAMAIC LETTER WAW;Lo;0;R;;;;;N;;;;; +10846;IMPERIAL ARAMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10847;IMPERIAL ARAMAIC LETTER HETH;Lo;0;R;;;;;N;;;;; +10848;IMPERIAL ARAMAIC LETTER TETH;Lo;0;R;;;;;N;;;;; +10849;IMPERIAL ARAMAIC LETTER YODH;Lo;0;R;;;;;N;;;;; +1084A;IMPERIAL ARAMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;; +1084B;IMPERIAL ARAMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +1084C;IMPERIAL ARAMAIC LETTER MEM;Lo;0;R;;;;;N;;;;; +1084D;IMPERIAL ARAMAIC LETTER NUN;Lo;0;R;;;;;N;;;;; +1084E;IMPERIAL ARAMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +1084F;IMPERIAL ARAMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;; +10850;IMPERIAL ARAMAIC LETTER PE;Lo;0;R;;;;;N;;;;; +10851;IMPERIAL ARAMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;; +10852;IMPERIAL ARAMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;; +10853;IMPERIAL ARAMAIC LETTER RESH;Lo;0;R;;;;;N;;;;; +10854;IMPERIAL ARAMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;; +10855;IMPERIAL ARAMAIC LETTER TAW;Lo;0;R;;;;;N;;;;; +10857;IMPERIAL ARAMAIC SECTION SIGN;Po;0;R;;;;;N;;;;; +10858;IMPERIAL ARAMAIC NUMBER ONE;No;0;R;;;;1;N;;;;; +10859;IMPERIAL ARAMAIC NUMBER TWO;No;0;R;;;;2;N;;;;; +1085A;IMPERIAL ARAMAIC NUMBER THREE;No;0;R;;;;3;N;;;;; +1085B;IMPERIAL ARAMAIC NUMBER TEN;No;0;R;;;;10;N;;;;; +1085C;IMPERIAL ARAMAIC NUMBER TWENTY;No;0;R;;;;20;N;;;;; +1085D;IMPERIAL ARAMAIC NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +1085E;IMPERIAL ARAMAIC NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +1085F;IMPERIAL ARAMAIC NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;; 10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;; 10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;; 10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;; @@ -15593,6 +16584,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;; 10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; 10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +1091A;PHOENICIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +1091B;PHOENICIAN NUMBER THREE;No;0;R;;;;3;N;;;;; 1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;; 10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;; 10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;; @@ -15686,6 +16679,326 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;; 10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;; 10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;; +10A60;OLD SOUTH ARABIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10A61;OLD SOUTH ARABIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10A62;OLD SOUTH ARABIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10A63;OLD SOUTH ARABIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10A64;OLD SOUTH ARABIAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +10A65;OLD SOUTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10A66;OLD SOUTH ARABIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10A67;OLD SOUTH ARABIAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10A68;OLD SOUTH ARABIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10A69;OLD SOUTH ARABIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10A6A;OLD SOUTH ARABIAN LETTER SAT;Lo;0;R;;;;;N;;;;; +10A6B;OLD SOUTH ARABIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10A6C;OLD SOUTH ARABIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10A6D;OLD SOUTH ARABIAN LETTER KHETH;Lo;0;R;;;;;N;;;;; +10A6E;OLD SOUTH ARABIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10A6F;OLD SOUTH ARABIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10A70;OLD SOUTH ARABIAN LETTER FE;Lo;0;R;;;;;N;;;;; +10A71;OLD SOUTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;; +10A72;OLD SOUTH ARABIAN LETTER AYN;Lo;0;R;;;;;N;;;;; +10A73;OLD SOUTH ARABIAN LETTER DHADHE;Lo;0;R;;;;;N;;;;; +10A74;OLD SOUTH ARABIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10A75;OLD SOUTH ARABIAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10A76;OLD SOUTH ARABIAN LETTER GHAYN;Lo;0;R;;;;;N;;;;; +10A77;OLD SOUTH ARABIAN LETTER TETH;Lo;0;R;;;;;N;;;;; +10A78;OLD SOUTH ARABIAN LETTER ZAYN;Lo;0;R;;;;;N;;;;; +10A79;OLD SOUTH ARABIAN LETTER DHALETH;Lo;0;R;;;;;N;;;;; +10A7A;OLD SOUTH ARABIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10A7B;OLD SOUTH ARABIAN LETTER THAW;Lo;0;R;;;;;N;;;;; +10A7C;OLD SOUTH ARABIAN LETTER THETH;Lo;0;R;;;;;N;;;;; +10A7D;OLD SOUTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10A7E;OLD SOUTH ARABIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;; +10A7F;OLD SOUTH ARABIAN NUMERIC INDICATOR;Po;0;R;;;;;N;;;;; +10B00;AVESTAN LETTER A;Lo;0;R;;;;;N;;;;; +10B01;AVESTAN LETTER AA;Lo;0;R;;;;;N;;;;; +10B02;AVESTAN LETTER AO;Lo;0;R;;;;;N;;;;; +10B03;AVESTAN LETTER AAO;Lo;0;R;;;;;N;;;;; +10B04;AVESTAN LETTER AN;Lo;0;R;;;;;N;;;;; +10B05;AVESTAN LETTER AAN;Lo;0;R;;;;;N;;;;; +10B06;AVESTAN LETTER AE;Lo;0;R;;;;;N;;;;; +10B07;AVESTAN LETTER AEE;Lo;0;R;;;;;N;;;;; +10B08;AVESTAN LETTER E;Lo;0;R;;;;;N;;;;; +10B09;AVESTAN LETTER EE;Lo;0;R;;;;;N;;;;; +10B0A;AVESTAN LETTER O;Lo;0;R;;;;;N;;;;; +10B0B;AVESTAN LETTER OO;Lo;0;R;;;;;N;;;;; +10B0C;AVESTAN LETTER I;Lo;0;R;;;;;N;;;;; +10B0D;AVESTAN LETTER II;Lo;0;R;;;;;N;;;;; +10B0E;AVESTAN LETTER U;Lo;0;R;;;;;N;;;;; +10B0F;AVESTAN LETTER UU;Lo;0;R;;;;;N;;;;; +10B10;AVESTAN LETTER KE;Lo;0;R;;;;;N;;;;; +10B11;AVESTAN LETTER XE;Lo;0;R;;;;;N;;;;; +10B12;AVESTAN LETTER XYE;Lo;0;R;;;;;N;;;;; +10B13;AVESTAN LETTER XVE;Lo;0;R;;;;;N;;;;; +10B14;AVESTAN LETTER GE;Lo;0;R;;;;;N;;;;; +10B15;AVESTAN LETTER GGE;Lo;0;R;;;;;N;;;;; +10B16;AVESTAN LETTER GHE;Lo;0;R;;;;;N;;;;; +10B17;AVESTAN LETTER CE;Lo;0;R;;;;;N;;;;; +10B18;AVESTAN LETTER JE;Lo;0;R;;;;;N;;;;; +10B19;AVESTAN LETTER TE;Lo;0;R;;;;;N;;;;; +10B1A;AVESTAN LETTER THE;Lo;0;R;;;;;N;;;;; +10B1B;AVESTAN LETTER DE;Lo;0;R;;;;;N;;;;; +10B1C;AVESTAN LETTER DHE;Lo;0;R;;;;;N;;;;; +10B1D;AVESTAN LETTER TTE;Lo;0;R;;;;;N;;;;; +10B1E;AVESTAN LETTER PE;Lo;0;R;;;;;N;;;;; +10B1F;AVESTAN LETTER FE;Lo;0;R;;;;;N;;;;; +10B20;AVESTAN LETTER BE;Lo;0;R;;;;;N;;;;; +10B21;AVESTAN LETTER BHE;Lo;0;R;;;;;N;;;;; +10B22;AVESTAN LETTER NGE;Lo;0;R;;;;;N;;;;; +10B23;AVESTAN LETTER NGYE;Lo;0;R;;;;;N;;;;; +10B24;AVESTAN LETTER NGVE;Lo;0;R;;;;;N;;;;; +10B25;AVESTAN LETTER NE;Lo;0;R;;;;;N;;;;; +10B26;AVESTAN LETTER NYE;Lo;0;R;;;;;N;;;;; +10B27;AVESTAN LETTER NNE;Lo;0;R;;;;;N;;;;; +10B28;AVESTAN LETTER ME;Lo;0;R;;;;;N;;;;; +10B29;AVESTAN LETTER HME;Lo;0;R;;;;;N;;;;; +10B2A;AVESTAN LETTER YYE;Lo;0;R;;;;;N;;;;; +10B2B;AVESTAN LETTER YE;Lo;0;R;;;;;N;;;;; +10B2C;AVESTAN LETTER VE;Lo;0;R;;;;;N;;;;; +10B2D;AVESTAN LETTER RE;Lo;0;R;;;;;N;;;;; +10B2E;AVESTAN LETTER LE;Lo;0;R;;;;;N;;;;; +10B2F;AVESTAN LETTER SE;Lo;0;R;;;;;N;;;;; +10B30;AVESTAN LETTER ZE;Lo;0;R;;;;;N;;;;; +10B31;AVESTAN LETTER SHE;Lo;0;R;;;;;N;;;;; +10B32;AVESTAN LETTER ZHE;Lo;0;R;;;;;N;;;;; +10B33;AVESTAN LETTER SHYE;Lo;0;R;;;;;N;;;;; +10B34;AVESTAN LETTER SSHE;Lo;0;R;;;;;N;;;;; +10B35;AVESTAN LETTER HE;Lo;0;R;;;;;N;;;;; +10B39;AVESTAN ABBREVIATION MARK;Po;0;ON;;;;;N;;;;; +10B3A;TINY TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3B;SMALL TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3C;LARGE TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3D;LARGE ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3E;LARGE TWO RINGS OVER ONE RING PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3F;LARGE ONE RING OVER TWO RINGS PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B40;INSCRIPTIONAL PARTHIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10B41;INSCRIPTIONAL PARTHIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10B42;INSCRIPTIONAL PARTHIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10B43;INSCRIPTIONAL PARTHIAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10B44;INSCRIPTIONAL PARTHIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10B45;INSCRIPTIONAL PARTHIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10B46;INSCRIPTIONAL PARTHIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10B47;INSCRIPTIONAL PARTHIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10B48;INSCRIPTIONAL PARTHIAN LETTER TETH;Lo;0;R;;;;;N;;;;; +10B49;INSCRIPTIONAL PARTHIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10B4A;INSCRIPTIONAL PARTHIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10B4B;INSCRIPTIONAL PARTHIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10B4C;INSCRIPTIONAL PARTHIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10B4D;INSCRIPTIONAL PARTHIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10B4E;INSCRIPTIONAL PARTHIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10B4F;INSCRIPTIONAL PARTHIAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10B50;INSCRIPTIONAL PARTHIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10B51;INSCRIPTIONAL PARTHIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10B52;INSCRIPTIONAL PARTHIAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +10B53;INSCRIPTIONAL PARTHIAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10B54;INSCRIPTIONAL PARTHIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10B55;INSCRIPTIONAL PARTHIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10B58;INSCRIPTIONAL PARTHIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10B59;INSCRIPTIONAL PARTHIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +10B5A;INSCRIPTIONAL PARTHIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +10B5B;INSCRIPTIONAL PARTHIAN NUMBER FOUR;No;0;R;;;;4;N;;;;; +10B5C;INSCRIPTIONAL PARTHIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10B5D;INSCRIPTIONAL PARTHIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10B5E;INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10B5F;INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10B60;INSCRIPTIONAL PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10B61;INSCRIPTIONAL PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;; +10B62;INSCRIPTIONAL PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10B63;INSCRIPTIONAL PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;; +10B64;INSCRIPTIONAL PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;; +10B65;INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;; +10B66;INSCRIPTIONAL PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10B67;INSCRIPTIONAL PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;; +10B68;INSCRIPTIONAL PAHLAVI LETTER TETH;Lo;0;R;;;;;N;;;;; +10B69;INSCRIPTIONAL PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;; +10B6A;INSCRIPTIONAL PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;; +10B6B;INSCRIPTIONAL PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10B6C;INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;; +10B6D;INSCRIPTIONAL PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;; +10B6E;INSCRIPTIONAL PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10B6F;INSCRIPTIONAL PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;; +10B70;INSCRIPTIONAL PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;; +10B71;INSCRIPTIONAL PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;; +10B72;INSCRIPTIONAL PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;; +10B78;INSCRIPTIONAL PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;; +10B79;INSCRIPTIONAL PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;; +10B7A;INSCRIPTIONAL PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;; +10B7B;INSCRIPTIONAL PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;; +10B7C;INSCRIPTIONAL PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;; +10B7D;INSCRIPTIONAL PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10B7E;INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10B7F;INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10C00;OLD TURKIC LETTER ORKHON A;Lo;0;R;;;;;N;;;;; +10C01;OLD TURKIC LETTER YENISEI A;Lo;0;R;;;;;N;;;;; +10C02;OLD TURKIC LETTER YENISEI AE;Lo;0;R;;;;;N;;;;; +10C03;OLD TURKIC LETTER ORKHON I;Lo;0;R;;;;;N;;;;; +10C04;OLD TURKIC LETTER YENISEI I;Lo;0;R;;;;;N;;;;; +10C05;OLD TURKIC LETTER YENISEI E;Lo;0;R;;;;;N;;;;; +10C06;OLD TURKIC LETTER ORKHON O;Lo;0;R;;;;;N;;;;; +10C07;OLD TURKIC LETTER ORKHON OE;Lo;0;R;;;;;N;;;;; +10C08;OLD TURKIC LETTER YENISEI OE;Lo;0;R;;;;;N;;;;; +10C09;OLD TURKIC LETTER ORKHON AB;Lo;0;R;;;;;N;;;;; +10C0A;OLD TURKIC LETTER YENISEI AB;Lo;0;R;;;;;N;;;;; +10C0B;OLD TURKIC LETTER ORKHON AEB;Lo;0;R;;;;;N;;;;; +10C0C;OLD TURKIC LETTER YENISEI AEB;Lo;0;R;;;;;N;;;;; +10C0D;OLD TURKIC LETTER ORKHON AG;Lo;0;R;;;;;N;;;;; +10C0E;OLD TURKIC LETTER YENISEI AG;Lo;0;R;;;;;N;;;;; +10C0F;OLD TURKIC LETTER ORKHON AEG;Lo;0;R;;;;;N;;;;; +10C10;OLD TURKIC LETTER YENISEI AEG;Lo;0;R;;;;;N;;;;; +10C11;OLD TURKIC LETTER ORKHON AD;Lo;0;R;;;;;N;;;;; +10C12;OLD TURKIC LETTER YENISEI AD;Lo;0;R;;;;;N;;;;; +10C13;OLD TURKIC LETTER ORKHON AED;Lo;0;R;;;;;N;;;;; +10C14;OLD TURKIC LETTER ORKHON EZ;Lo;0;R;;;;;N;;;;; +10C15;OLD TURKIC LETTER YENISEI EZ;Lo;0;R;;;;;N;;;;; +10C16;OLD TURKIC LETTER ORKHON AY;Lo;0;R;;;;;N;;;;; +10C17;OLD TURKIC LETTER YENISEI AY;Lo;0;R;;;;;N;;;;; +10C18;OLD TURKIC LETTER ORKHON AEY;Lo;0;R;;;;;N;;;;; +10C19;OLD TURKIC LETTER YENISEI AEY;Lo;0;R;;;;;N;;;;; +10C1A;OLD TURKIC LETTER ORKHON AEK;Lo;0;R;;;;;N;;;;; +10C1B;OLD TURKIC LETTER YENISEI AEK;Lo;0;R;;;;;N;;;;; +10C1C;OLD TURKIC LETTER ORKHON OEK;Lo;0;R;;;;;N;;;;; +10C1D;OLD TURKIC LETTER YENISEI OEK;Lo;0;R;;;;;N;;;;; +10C1E;OLD TURKIC LETTER ORKHON AL;Lo;0;R;;;;;N;;;;; +10C1F;OLD TURKIC LETTER YENISEI AL;Lo;0;R;;;;;N;;;;; +10C20;OLD TURKIC LETTER ORKHON AEL;Lo;0;R;;;;;N;;;;; +10C21;OLD TURKIC LETTER ORKHON ELT;Lo;0;R;;;;;N;;;;; +10C22;OLD TURKIC LETTER ORKHON EM;Lo;0;R;;;;;N;;;;; +10C23;OLD TURKIC LETTER ORKHON AN;Lo;0;R;;;;;N;;;;; +10C24;OLD TURKIC LETTER ORKHON AEN;Lo;0;R;;;;;N;;;;; +10C25;OLD TURKIC LETTER YENISEI AEN;Lo;0;R;;;;;N;;;;; +10C26;OLD TURKIC LETTER ORKHON ENT;Lo;0;R;;;;;N;;;;; +10C27;OLD TURKIC LETTER YENISEI ENT;Lo;0;R;;;;;N;;;;; +10C28;OLD TURKIC LETTER ORKHON ENC;Lo;0;R;;;;;N;;;;; +10C29;OLD TURKIC LETTER YENISEI ENC;Lo;0;R;;;;;N;;;;; +10C2A;OLD TURKIC LETTER ORKHON ENY;Lo;0;R;;;;;N;;;;; +10C2B;OLD TURKIC LETTER YENISEI ENY;Lo;0;R;;;;;N;;;;; +10C2C;OLD TURKIC LETTER YENISEI ANG;Lo;0;R;;;;;N;;;;; +10C2D;OLD TURKIC LETTER ORKHON ENG;Lo;0;R;;;;;N;;;;; +10C2E;OLD TURKIC LETTER YENISEI AENG;Lo;0;R;;;;;N;;;;; +10C2F;OLD TURKIC LETTER ORKHON EP;Lo;0;R;;;;;N;;;;; +10C30;OLD TURKIC LETTER ORKHON OP;Lo;0;R;;;;;N;;;;; +10C31;OLD TURKIC LETTER ORKHON IC;Lo;0;R;;;;;N;;;;; +10C32;OLD TURKIC LETTER ORKHON EC;Lo;0;R;;;;;N;;;;; +10C33;OLD TURKIC LETTER YENISEI EC;Lo;0;R;;;;;N;;;;; +10C34;OLD TURKIC LETTER ORKHON AQ;Lo;0;R;;;;;N;;;;; +10C35;OLD TURKIC LETTER YENISEI AQ;Lo;0;R;;;;;N;;;;; +10C36;OLD TURKIC LETTER ORKHON IQ;Lo;0;R;;;;;N;;;;; +10C37;OLD TURKIC LETTER YENISEI IQ;Lo;0;R;;;;;N;;;;; +10C38;OLD TURKIC LETTER ORKHON OQ;Lo;0;R;;;;;N;;;;; +10C39;OLD TURKIC LETTER YENISEI OQ;Lo;0;R;;;;;N;;;;; +10C3A;OLD TURKIC LETTER ORKHON AR;Lo;0;R;;;;;N;;;;; +10C3B;OLD TURKIC LETTER YENISEI AR;Lo;0;R;;;;;N;;;;; +10C3C;OLD TURKIC LETTER ORKHON AER;Lo;0;R;;;;;N;;;;; +10C3D;OLD TURKIC LETTER ORKHON AS;Lo;0;R;;;;;N;;;;; +10C3E;OLD TURKIC LETTER ORKHON AES;Lo;0;R;;;;;N;;;;; +10C3F;OLD TURKIC LETTER ORKHON ASH;Lo;0;R;;;;;N;;;;; +10C40;OLD TURKIC LETTER YENISEI ASH;Lo;0;R;;;;;N;;;;; +10C41;OLD TURKIC LETTER ORKHON ESH;Lo;0;R;;;;;N;;;;; +10C42;OLD TURKIC LETTER YENISEI ESH;Lo;0;R;;;;;N;;;;; +10C43;OLD TURKIC LETTER ORKHON AT;Lo;0;R;;;;;N;;;;; +10C44;OLD TURKIC LETTER YENISEI AT;Lo;0;R;;;;;N;;;;; +10C45;OLD TURKIC LETTER ORKHON AET;Lo;0;R;;;;;N;;;;; +10C46;OLD TURKIC LETTER YENISEI AET;Lo;0;R;;;;;N;;;;; +10C47;OLD TURKIC LETTER ORKHON OT;Lo;0;R;;;;;N;;;;; +10C48;OLD TURKIC LETTER ORKHON BASH;Lo;0;R;;;;;N;;;;; +10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;; +10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;; +10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;; +10E63;RUMI DIGIT FOUR;No;0;AN;;;4;4;N;;;;; +10E64;RUMI DIGIT FIVE;No;0;AN;;;5;5;N;;;;; +10E65;RUMI DIGIT SIX;No;0;AN;;;6;6;N;;;;; +10E66;RUMI DIGIT SEVEN;No;0;AN;;;7;7;N;;;;; +10E67;RUMI DIGIT EIGHT;No;0;AN;;;8;8;N;;;;; +10E68;RUMI DIGIT NINE;No;0;AN;;;9;9;N;;;;; +10E69;RUMI NUMBER TEN;No;0;AN;;;;10;N;;;;; +10E6A;RUMI NUMBER TWENTY;No;0;AN;;;;20;N;;;;; +10E6B;RUMI NUMBER THIRTY;No;0;AN;;;;30;N;;;;; +10E6C;RUMI NUMBER FORTY;No;0;AN;;;;40;N;;;;; +10E6D;RUMI NUMBER FIFTY;No;0;AN;;;;50;N;;;;; +10E6E;RUMI NUMBER SIXTY;No;0;AN;;;;60;N;;;;; +10E6F;RUMI NUMBER SEVENTY;No;0;AN;;;;70;N;;;;; +10E70;RUMI NUMBER EIGHTY;No;0;AN;;;;80;N;;;;; +10E71;RUMI NUMBER NINETY;No;0;AN;;;;90;N;;;;; +10E72;RUMI NUMBER ONE HUNDRED;No;0;AN;;;;100;N;;;;; +10E73;RUMI NUMBER TWO HUNDRED;No;0;AN;;;;200;N;;;;; +10E74;RUMI NUMBER THREE HUNDRED;No;0;AN;;;;300;N;;;;; +10E75;RUMI NUMBER FOUR HUNDRED;No;0;AN;;;;400;N;;;;; +10E76;RUMI NUMBER FIVE HUNDRED;No;0;AN;;;;500;N;;;;; +10E77;RUMI NUMBER SIX HUNDRED;No;0;AN;;;;600;N;;;;; +10E78;RUMI NUMBER SEVEN HUNDRED;No;0;AN;;;;700;N;;;;; +10E79;RUMI NUMBER EIGHT HUNDRED;No;0;AN;;;;800;N;;;;; +10E7A;RUMI NUMBER NINE HUNDRED;No;0;AN;;;;900;N;;;;; +10E7B;RUMI FRACTION ONE HALF;No;0;AN;;;;1/2;N;;;;; +10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;; +10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;; +10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;; +11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11082;KAITHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11083;KAITHI LETTER A;Lo;0;L;;;;;N;;;;; +11084;KAITHI LETTER AA;Lo;0;L;;;;;N;;;;; +11085;KAITHI LETTER I;Lo;0;L;;;;;N;;;;; +11086;KAITHI LETTER II;Lo;0;L;;;;;N;;;;; +11087;KAITHI LETTER U;Lo;0;L;;;;;N;;;;; +11088;KAITHI LETTER UU;Lo;0;L;;;;;N;;;;; +11089;KAITHI LETTER E;Lo;0;L;;;;;N;;;;; +1108A;KAITHI LETTER AI;Lo;0;L;;;;;N;;;;; +1108B;KAITHI LETTER O;Lo;0;L;;;;;N;;;;; +1108C;KAITHI LETTER AU;Lo;0;L;;;;;N;;;;; +1108D;KAITHI LETTER KA;Lo;0;L;;;;;N;;;;; +1108E;KAITHI LETTER KHA;Lo;0;L;;;;;N;;;;; +1108F;KAITHI LETTER GA;Lo;0;L;;;;;N;;;;; +11090;KAITHI LETTER GHA;Lo;0;L;;;;;N;;;;; +11091;KAITHI LETTER NGA;Lo;0;L;;;;;N;;;;; +11092;KAITHI LETTER CA;Lo;0;L;;;;;N;;;;; +11093;KAITHI LETTER CHA;Lo;0;L;;;;;N;;;;; +11094;KAITHI LETTER JA;Lo;0;L;;;;;N;;;;; +11095;KAITHI LETTER JHA;Lo;0;L;;;;;N;;;;; +11096;KAITHI LETTER NYA;Lo;0;L;;;;;N;;;;; +11097;KAITHI LETTER TTA;Lo;0;L;;;;;N;;;;; +11098;KAITHI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11099;KAITHI LETTER DDA;Lo;0;L;;;;;N;;;;; +1109A;KAITHI LETTER DDDHA;Lo;0;L;11099 110BA;;;;N;;;;; +1109B;KAITHI LETTER DDHA;Lo;0;L;;;;;N;;;;; +1109C;KAITHI LETTER RHA;Lo;0;L;1109B 110BA;;;;N;;;;; +1109D;KAITHI LETTER NNA;Lo;0;L;;;;;N;;;;; +1109E;KAITHI LETTER TA;Lo;0;L;;;;;N;;;;; +1109F;KAITHI LETTER THA;Lo;0;L;;;;;N;;;;; +110A0;KAITHI LETTER DA;Lo;0;L;;;;;N;;;;; +110A1;KAITHI LETTER DHA;Lo;0;L;;;;;N;;;;; +110A2;KAITHI LETTER NA;Lo;0;L;;;;;N;;;;; +110A3;KAITHI LETTER PA;Lo;0;L;;;;;N;;;;; +110A4;KAITHI LETTER PHA;Lo;0;L;;;;;N;;;;; +110A5;KAITHI LETTER BA;Lo;0;L;;;;;N;;;;; +110A6;KAITHI LETTER BHA;Lo;0;L;;;;;N;;;;; +110A7;KAITHI LETTER MA;Lo;0;L;;;;;N;;;;; +110A8;KAITHI LETTER YA;Lo;0;L;;;;;N;;;;; +110A9;KAITHI LETTER RA;Lo;0;L;;;;;N;;;;; +110AA;KAITHI LETTER LA;Lo;0;L;;;;;N;;;;; +110AB;KAITHI LETTER VA;Lo;0;L;110A5 110BA;;;;N;;;;; +110AC;KAITHI LETTER SHA;Lo;0;L;;;;;N;;;;; +110AD;KAITHI LETTER SSA;Lo;0;L;;;;;N;;;;; +110AE;KAITHI LETTER SA;Lo;0;L;;;;;N;;;;; +110AF;KAITHI LETTER HA;Lo;0;L;;;;;N;;;;; +110B0;KAITHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +110B1;KAITHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +110B2;KAITHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +110B3;KAITHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +110B4;KAITHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +110B5;KAITHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +110B6;KAITHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +110B7;KAITHI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +110B8;KAITHI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +110B9;KAITHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +110BA;KAITHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +110BB;KAITHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +110BC;KAITHI ENUMERATION SIGN;Po;0;L;;;;;N;;;;; +110BD;KAITHI NUMBER SIGN;Cf;0;L;;;;;N;;;;; +110BE;KAITHI SECTION MARK;Po;0;L;;;;;N;;;;; +110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;; +110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;; +110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;; 12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;; 12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;; 12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;; @@ -16668,6 +17981,1077 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;; 12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;; 12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;; +13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; +13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; +13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; +13003;EGYPTIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;; +13004;EGYPTIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;; +13005;EGYPTIAN HIEROGLYPH A005A;Lo;0;L;;;;;N;;;;; +13006;EGYPTIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;; +13007;EGYPTIAN HIEROGLYPH A006A;Lo;0;L;;;;;N;;;;; +13008;EGYPTIAN HIEROGLYPH A006B;Lo;0;L;;;;;N;;;;; +13009;EGYPTIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;; +1300A;EGYPTIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;; +1300B;EGYPTIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;; +1300C;EGYPTIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;; +1300D;EGYPTIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;; +1300E;EGYPTIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;; +1300F;EGYPTIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;; +13010;EGYPTIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;; +13011;EGYPTIAN HIEROGLYPH A014A;Lo;0;L;;;;;N;;;;; +13012;EGYPTIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;; +13013;EGYPTIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;; +13014;EGYPTIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;; +13015;EGYPTIAN HIEROGLYPH A017A;Lo;0;L;;;;;N;;;;; +13016;EGYPTIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;; +13017;EGYPTIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;; +13018;EGYPTIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;; +13019;EGYPTIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;; +1301A;EGYPTIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;; +1301B;EGYPTIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;; +1301C;EGYPTIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;; +1301D;EGYPTIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;; +1301E;EGYPTIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;; +1301F;EGYPTIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;; +13020;EGYPTIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;; +13021;EGYPTIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;; +13022;EGYPTIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;; +13023;EGYPTIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;; +13024;EGYPTIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;; +13025;EGYPTIAN HIEROGLYPH A032A;Lo;0;L;;;;;N;;;;; +13026;EGYPTIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;; +13027;EGYPTIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;; +13028;EGYPTIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;; +13029;EGYPTIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;; +1302A;EGYPTIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;; +1302B;EGYPTIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;; +1302C;EGYPTIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;; +1302D;EGYPTIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;; +1302E;EGYPTIAN HIEROGLYPH A040A;Lo;0;L;;;;;N;;;;; +1302F;EGYPTIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;; +13030;EGYPTIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;; +13031;EGYPTIAN HIEROGLYPH A042A;Lo;0;L;;;;;N;;;;; +13032;EGYPTIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;; +13033;EGYPTIAN HIEROGLYPH A043A;Lo;0;L;;;;;N;;;;; +13034;EGYPTIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;; +13035;EGYPTIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;; +13036;EGYPTIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;; +13037;EGYPTIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;; +13038;EGYPTIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;; +13039;EGYPTIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;; +1303A;EGYPTIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;; +1303B;EGYPTIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;; +1303C;EGYPTIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;; +1303D;EGYPTIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;; +1303E;EGYPTIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;; +1303F;EGYPTIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;; +13040;EGYPTIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;; +13041;EGYPTIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;; +13042;EGYPTIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;; +13043;EGYPTIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;; +13044;EGYPTIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;; +13045;EGYPTIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;; +13046;EGYPTIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;; +13047;EGYPTIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;; +13048;EGYPTIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;; +13049;EGYPTIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;; +1304A;EGYPTIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;; +1304B;EGYPTIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;; +1304C;EGYPTIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;; +1304D;EGYPTIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;; +1304E;EGYPTIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;; +1304F;EGYPTIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;; +13050;EGYPTIAN HIEROGLYPH B001;Lo;0;L;;;;;N;;;;; +13051;EGYPTIAN HIEROGLYPH B002;Lo;0;L;;;;;N;;;;; +13052;EGYPTIAN HIEROGLYPH B003;Lo;0;L;;;;;N;;;;; +13053;EGYPTIAN HIEROGLYPH B004;Lo;0;L;;;;;N;;;;; +13054;EGYPTIAN HIEROGLYPH B005;Lo;0;L;;;;;N;;;;; +13055;EGYPTIAN HIEROGLYPH B005A;Lo;0;L;;;;;N;;;;; +13056;EGYPTIAN HIEROGLYPH B006;Lo;0;L;;;;;N;;;;; +13057;EGYPTIAN HIEROGLYPH B007;Lo;0;L;;;;;N;;;;; +13058;EGYPTIAN HIEROGLYPH B008;Lo;0;L;;;;;N;;;;; +13059;EGYPTIAN HIEROGLYPH B009;Lo;0;L;;;;;N;;;;; +1305A;EGYPTIAN HIEROGLYPH C001;Lo;0;L;;;;;N;;;;; +1305B;EGYPTIAN HIEROGLYPH C002;Lo;0;L;;;;;N;;;;; +1305C;EGYPTIAN HIEROGLYPH C002A;Lo;0;L;;;;;N;;;;; +1305D;EGYPTIAN HIEROGLYPH C002B;Lo;0;L;;;;;N;;;;; +1305E;EGYPTIAN HIEROGLYPH C002C;Lo;0;L;;;;;N;;;;; +1305F;EGYPTIAN HIEROGLYPH C003;Lo;0;L;;;;;N;;;;; +13060;EGYPTIAN HIEROGLYPH C004;Lo;0;L;;;;;N;;;;; +13061;EGYPTIAN HIEROGLYPH C005;Lo;0;L;;;;;N;;;;; +13062;EGYPTIAN HIEROGLYPH C006;Lo;0;L;;;;;N;;;;; +13063;EGYPTIAN HIEROGLYPH C007;Lo;0;L;;;;;N;;;;; +13064;EGYPTIAN HIEROGLYPH C008;Lo;0;L;;;;;N;;;;; +13065;EGYPTIAN HIEROGLYPH C009;Lo;0;L;;;;;N;;;;; +13066;EGYPTIAN HIEROGLYPH C010;Lo;0;L;;;;;N;;;;; +13067;EGYPTIAN HIEROGLYPH C010A;Lo;0;L;;;;;N;;;;; +13068;EGYPTIAN HIEROGLYPH C011;Lo;0;L;;;;;N;;;;; +13069;EGYPTIAN HIEROGLYPH C012;Lo;0;L;;;;;N;;;;; +1306A;EGYPTIAN HIEROGLYPH C013;Lo;0;L;;;;;N;;;;; +1306B;EGYPTIAN HIEROGLYPH C014;Lo;0;L;;;;;N;;;;; +1306C;EGYPTIAN HIEROGLYPH C015;Lo;0;L;;;;;N;;;;; +1306D;EGYPTIAN HIEROGLYPH C016;Lo;0;L;;;;;N;;;;; +1306E;EGYPTIAN HIEROGLYPH C017;Lo;0;L;;;;;N;;;;; +1306F;EGYPTIAN HIEROGLYPH C018;Lo;0;L;;;;;N;;;;; +13070;EGYPTIAN HIEROGLYPH C019;Lo;0;L;;;;;N;;;;; +13071;EGYPTIAN HIEROGLYPH C020;Lo;0;L;;;;;N;;;;; +13072;EGYPTIAN HIEROGLYPH C021;Lo;0;L;;;;;N;;;;; +13073;EGYPTIAN HIEROGLYPH C022;Lo;0;L;;;;;N;;;;; +13074;EGYPTIAN HIEROGLYPH C023;Lo;0;L;;;;;N;;;;; +13075;EGYPTIAN HIEROGLYPH C024;Lo;0;L;;;;;N;;;;; +13076;EGYPTIAN HIEROGLYPH D001;Lo;0;L;;;;;N;;;;; +13077;EGYPTIAN HIEROGLYPH D002;Lo;0;L;;;;;N;;;;; +13078;EGYPTIAN HIEROGLYPH D003;Lo;0;L;;;;;N;;;;; +13079;EGYPTIAN HIEROGLYPH D004;Lo;0;L;;;;;N;;;;; +1307A;EGYPTIAN HIEROGLYPH D005;Lo;0;L;;;;;N;;;;; +1307B;EGYPTIAN HIEROGLYPH D006;Lo;0;L;;;;;N;;;;; +1307C;EGYPTIAN HIEROGLYPH D007;Lo;0;L;;;;;N;;;;; +1307D;EGYPTIAN HIEROGLYPH D008;Lo;0;L;;;;;N;;;;; +1307E;EGYPTIAN HIEROGLYPH D008A;Lo;0;L;;;;;N;;;;; +1307F;EGYPTIAN HIEROGLYPH D009;Lo;0;L;;;;;N;;;;; +13080;EGYPTIAN HIEROGLYPH D010;Lo;0;L;;;;;N;;;;; +13081;EGYPTIAN HIEROGLYPH D011;Lo;0;L;;;;;N;;;;; +13082;EGYPTIAN HIEROGLYPH D012;Lo;0;L;;;;;N;;;;; +13083;EGYPTIAN HIEROGLYPH D013;Lo;0;L;;;;;N;;;;; +13084;EGYPTIAN HIEROGLYPH D014;Lo;0;L;;;;;N;;;;; +13085;EGYPTIAN HIEROGLYPH D015;Lo;0;L;;;;;N;;;;; +13086;EGYPTIAN HIEROGLYPH D016;Lo;0;L;;;;;N;;;;; +13087;EGYPTIAN HIEROGLYPH D017;Lo;0;L;;;;;N;;;;; +13088;EGYPTIAN HIEROGLYPH D018;Lo;0;L;;;;;N;;;;; +13089;EGYPTIAN HIEROGLYPH D019;Lo;0;L;;;;;N;;;;; +1308A;EGYPTIAN HIEROGLYPH D020;Lo;0;L;;;;;N;;;;; +1308B;EGYPTIAN HIEROGLYPH D021;Lo;0;L;;;;;N;;;;; +1308C;EGYPTIAN HIEROGLYPH D022;Lo;0;L;;;;;N;;;;; +1308D;EGYPTIAN HIEROGLYPH D023;Lo;0;L;;;;;N;;;;; +1308E;EGYPTIAN HIEROGLYPH D024;Lo;0;L;;;;;N;;;;; +1308F;EGYPTIAN HIEROGLYPH D025;Lo;0;L;;;;;N;;;;; +13090;EGYPTIAN HIEROGLYPH D026;Lo;0;L;;;;;N;;;;; +13091;EGYPTIAN HIEROGLYPH D027;Lo;0;L;;;;;N;;;;; +13092;EGYPTIAN HIEROGLYPH D027A;Lo;0;L;;;;;N;;;;; +13093;EGYPTIAN HIEROGLYPH D028;Lo;0;L;;;;;N;;;;; +13094;EGYPTIAN HIEROGLYPH D029;Lo;0;L;;;;;N;;;;; +13095;EGYPTIAN HIEROGLYPH D030;Lo;0;L;;;;;N;;;;; +13096;EGYPTIAN HIEROGLYPH D031;Lo;0;L;;;;;N;;;;; +13097;EGYPTIAN HIEROGLYPH D031A;Lo;0;L;;;;;N;;;;; +13098;EGYPTIAN HIEROGLYPH D032;Lo;0;L;;;;;N;;;;; +13099;EGYPTIAN HIEROGLYPH D033;Lo;0;L;;;;;N;;;;; +1309A;EGYPTIAN HIEROGLYPH D034;Lo;0;L;;;;;N;;;;; +1309B;EGYPTIAN HIEROGLYPH D034A;Lo;0;L;;;;;N;;;;; +1309C;EGYPTIAN HIEROGLYPH D035;Lo;0;L;;;;;N;;;;; +1309D;EGYPTIAN HIEROGLYPH D036;Lo;0;L;;;;;N;;;;; +1309E;EGYPTIAN HIEROGLYPH D037;Lo;0;L;;;;;N;;;;; +1309F;EGYPTIAN HIEROGLYPH D038;Lo;0;L;;;;;N;;;;; +130A0;EGYPTIAN HIEROGLYPH D039;Lo;0;L;;;;;N;;;;; +130A1;EGYPTIAN HIEROGLYPH D040;Lo;0;L;;;;;N;;;;; +130A2;EGYPTIAN HIEROGLYPH D041;Lo;0;L;;;;;N;;;;; +130A3;EGYPTIAN HIEROGLYPH D042;Lo;0;L;;;;;N;;;;; +130A4;EGYPTIAN HIEROGLYPH D043;Lo;0;L;;;;;N;;;;; +130A5;EGYPTIAN HIEROGLYPH D044;Lo;0;L;;;;;N;;;;; +130A6;EGYPTIAN HIEROGLYPH D045;Lo;0;L;;;;;N;;;;; +130A7;EGYPTIAN HIEROGLYPH D046;Lo;0;L;;;;;N;;;;; +130A8;EGYPTIAN HIEROGLYPH D046A;Lo;0;L;;;;;N;;;;; +130A9;EGYPTIAN HIEROGLYPH D047;Lo;0;L;;;;;N;;;;; +130AA;EGYPTIAN HIEROGLYPH D048;Lo;0;L;;;;;N;;;;; +130AB;EGYPTIAN HIEROGLYPH D048A;Lo;0;L;;;;;N;;;;; +130AC;EGYPTIAN HIEROGLYPH D049;Lo;0;L;;;;;N;;;;; +130AD;EGYPTIAN HIEROGLYPH D050;Lo;0;L;;;;;N;;;;; +130AE;EGYPTIAN HIEROGLYPH D050A;Lo;0;L;;;;;N;;;;; +130AF;EGYPTIAN HIEROGLYPH D050B;Lo;0;L;;;;;N;;;;; +130B0;EGYPTIAN HIEROGLYPH D050C;Lo;0;L;;;;;N;;;;; +130B1;EGYPTIAN HIEROGLYPH D050D;Lo;0;L;;;;;N;;;;; +130B2;EGYPTIAN HIEROGLYPH D050E;Lo;0;L;;;;;N;;;;; +130B3;EGYPTIAN HIEROGLYPH D050F;Lo;0;L;;;;;N;;;;; +130B4;EGYPTIAN HIEROGLYPH D050G;Lo;0;L;;;;;N;;;;; +130B5;EGYPTIAN HIEROGLYPH D050H;Lo;0;L;;;;;N;;;;; +130B6;EGYPTIAN HIEROGLYPH D050I;Lo;0;L;;;;;N;;;;; +130B7;EGYPTIAN HIEROGLYPH D051;Lo;0;L;;;;;N;;;;; +130B8;EGYPTIAN HIEROGLYPH D052;Lo;0;L;;;;;N;;;;; +130B9;EGYPTIAN HIEROGLYPH D052A;Lo;0;L;;;;;N;;;;; +130BA;EGYPTIAN HIEROGLYPH D053;Lo;0;L;;;;;N;;;;; +130BB;EGYPTIAN HIEROGLYPH D054;Lo;0;L;;;;;N;;;;; +130BC;EGYPTIAN HIEROGLYPH D054A;Lo;0;L;;;;;N;;;;; +130BD;EGYPTIAN HIEROGLYPH D055;Lo;0;L;;;;;N;;;;; +130BE;EGYPTIAN HIEROGLYPH D056;Lo;0;L;;;;;N;;;;; +130BF;EGYPTIAN HIEROGLYPH D057;Lo;0;L;;;;;N;;;;; +130C0;EGYPTIAN HIEROGLYPH D058;Lo;0;L;;;;;N;;;;; +130C1;EGYPTIAN HIEROGLYPH D059;Lo;0;L;;;;;N;;;;; +130C2;EGYPTIAN HIEROGLYPH D060;Lo;0;L;;;;;N;;;;; +130C3;EGYPTIAN HIEROGLYPH D061;Lo;0;L;;;;;N;;;;; +130C4;EGYPTIAN HIEROGLYPH D062;Lo;0;L;;;;;N;;;;; +130C5;EGYPTIAN HIEROGLYPH D063;Lo;0;L;;;;;N;;;;; +130C6;EGYPTIAN HIEROGLYPH D064;Lo;0;L;;;;;N;;;;; +130C7;EGYPTIAN HIEROGLYPH D065;Lo;0;L;;;;;N;;;;; +130C8;EGYPTIAN HIEROGLYPH D066;Lo;0;L;;;;;N;;;;; +130C9;EGYPTIAN HIEROGLYPH D067;Lo;0;L;;;;;N;;;;; +130CA;EGYPTIAN HIEROGLYPH D067A;Lo;0;L;;;;;N;;;;; +130CB;EGYPTIAN HIEROGLYPH D067B;Lo;0;L;;;;;N;;;;; +130CC;EGYPTIAN HIEROGLYPH D067C;Lo;0;L;;;;;N;;;;; +130CD;EGYPTIAN HIEROGLYPH D067D;Lo;0;L;;;;;N;;;;; +130CE;EGYPTIAN HIEROGLYPH D067E;Lo;0;L;;;;;N;;;;; +130CF;EGYPTIAN HIEROGLYPH D067F;Lo;0;L;;;;;N;;;;; +130D0;EGYPTIAN HIEROGLYPH D067G;Lo;0;L;;;;;N;;;;; +130D1;EGYPTIAN HIEROGLYPH D067H;Lo;0;L;;;;;N;;;;; +130D2;EGYPTIAN HIEROGLYPH E001;Lo;0;L;;;;;N;;;;; +130D3;EGYPTIAN HIEROGLYPH E002;Lo;0;L;;;;;N;;;;; +130D4;EGYPTIAN HIEROGLYPH E003;Lo;0;L;;;;;N;;;;; +130D5;EGYPTIAN HIEROGLYPH E004;Lo;0;L;;;;;N;;;;; +130D6;EGYPTIAN HIEROGLYPH E005;Lo;0;L;;;;;N;;;;; +130D7;EGYPTIAN HIEROGLYPH E006;Lo;0;L;;;;;N;;;;; +130D8;EGYPTIAN HIEROGLYPH E007;Lo;0;L;;;;;N;;;;; +130D9;EGYPTIAN HIEROGLYPH E008;Lo;0;L;;;;;N;;;;; +130DA;EGYPTIAN HIEROGLYPH E008A;Lo;0;L;;;;;N;;;;; +130DB;EGYPTIAN HIEROGLYPH E009;Lo;0;L;;;;;N;;;;; +130DC;EGYPTIAN HIEROGLYPH E009A;Lo;0;L;;;;;N;;;;; +130DD;EGYPTIAN HIEROGLYPH E010;Lo;0;L;;;;;N;;;;; +130DE;EGYPTIAN HIEROGLYPH E011;Lo;0;L;;;;;N;;;;; +130DF;EGYPTIAN HIEROGLYPH E012;Lo;0;L;;;;;N;;;;; +130E0;EGYPTIAN HIEROGLYPH E013;Lo;0;L;;;;;N;;;;; +130E1;EGYPTIAN HIEROGLYPH E014;Lo;0;L;;;;;N;;;;; +130E2;EGYPTIAN HIEROGLYPH E015;Lo;0;L;;;;;N;;;;; +130E3;EGYPTIAN HIEROGLYPH E016;Lo;0;L;;;;;N;;;;; +130E4;EGYPTIAN HIEROGLYPH E016A;Lo;0;L;;;;;N;;;;; +130E5;EGYPTIAN HIEROGLYPH E017;Lo;0;L;;;;;N;;;;; +130E6;EGYPTIAN HIEROGLYPH E017A;Lo;0;L;;;;;N;;;;; +130E7;EGYPTIAN HIEROGLYPH E018;Lo;0;L;;;;;N;;;;; +130E8;EGYPTIAN HIEROGLYPH E019;Lo;0;L;;;;;N;;;;; +130E9;EGYPTIAN HIEROGLYPH E020;Lo;0;L;;;;;N;;;;; +130EA;EGYPTIAN HIEROGLYPH E020A;Lo;0;L;;;;;N;;;;; +130EB;EGYPTIAN HIEROGLYPH E021;Lo;0;L;;;;;N;;;;; +130EC;EGYPTIAN HIEROGLYPH E022;Lo;0;L;;;;;N;;;;; +130ED;EGYPTIAN HIEROGLYPH E023;Lo;0;L;;;;;N;;;;; +130EE;EGYPTIAN HIEROGLYPH E024;Lo;0;L;;;;;N;;;;; +130EF;EGYPTIAN HIEROGLYPH E025;Lo;0;L;;;;;N;;;;; +130F0;EGYPTIAN HIEROGLYPH E026;Lo;0;L;;;;;N;;;;; +130F1;EGYPTIAN HIEROGLYPH E027;Lo;0;L;;;;;N;;;;; +130F2;EGYPTIAN HIEROGLYPH E028;Lo;0;L;;;;;N;;;;; +130F3;EGYPTIAN HIEROGLYPH E028A;Lo;0;L;;;;;N;;;;; +130F4;EGYPTIAN HIEROGLYPH E029;Lo;0;L;;;;;N;;;;; +130F5;EGYPTIAN HIEROGLYPH E030;Lo;0;L;;;;;N;;;;; +130F6;EGYPTIAN HIEROGLYPH E031;Lo;0;L;;;;;N;;;;; +130F7;EGYPTIAN HIEROGLYPH E032;Lo;0;L;;;;;N;;;;; +130F8;EGYPTIAN HIEROGLYPH E033;Lo;0;L;;;;;N;;;;; +130F9;EGYPTIAN HIEROGLYPH E034;Lo;0;L;;;;;N;;;;; +130FA;EGYPTIAN HIEROGLYPH E034A;Lo;0;L;;;;;N;;;;; +130FB;EGYPTIAN HIEROGLYPH E036;Lo;0;L;;;;;N;;;;; +130FC;EGYPTIAN HIEROGLYPH E037;Lo;0;L;;;;;N;;;;; +130FD;EGYPTIAN HIEROGLYPH E038;Lo;0;L;;;;;N;;;;; +130FE;EGYPTIAN HIEROGLYPH F001;Lo;0;L;;;;;N;;;;; +130FF;EGYPTIAN HIEROGLYPH F001A;Lo;0;L;;;;;N;;;;; +13100;EGYPTIAN HIEROGLYPH F002;Lo;0;L;;;;;N;;;;; +13101;EGYPTIAN HIEROGLYPH F003;Lo;0;L;;;;;N;;;;; +13102;EGYPTIAN HIEROGLYPH F004;Lo;0;L;;;;;N;;;;; +13103;EGYPTIAN HIEROGLYPH F005;Lo;0;L;;;;;N;;;;; +13104;EGYPTIAN HIEROGLYPH F006;Lo;0;L;;;;;N;;;;; +13105;EGYPTIAN HIEROGLYPH F007;Lo;0;L;;;;;N;;;;; +13106;EGYPTIAN HIEROGLYPH F008;Lo;0;L;;;;;N;;;;; +13107;EGYPTIAN HIEROGLYPH F009;Lo;0;L;;;;;N;;;;; +13108;EGYPTIAN HIEROGLYPH F010;Lo;0;L;;;;;N;;;;; +13109;EGYPTIAN HIEROGLYPH F011;Lo;0;L;;;;;N;;;;; +1310A;EGYPTIAN HIEROGLYPH F012;Lo;0;L;;;;;N;;;;; +1310B;EGYPTIAN HIEROGLYPH F013;Lo;0;L;;;;;N;;;;; +1310C;EGYPTIAN HIEROGLYPH F013A;Lo;0;L;;;;;N;;;;; +1310D;EGYPTIAN HIEROGLYPH F014;Lo;0;L;;;;;N;;;;; +1310E;EGYPTIAN HIEROGLYPH F015;Lo;0;L;;;;;N;;;;; +1310F;EGYPTIAN HIEROGLYPH F016;Lo;0;L;;;;;N;;;;; +13110;EGYPTIAN HIEROGLYPH F017;Lo;0;L;;;;;N;;;;; +13111;EGYPTIAN HIEROGLYPH F018;Lo;0;L;;;;;N;;;;; +13112;EGYPTIAN HIEROGLYPH F019;Lo;0;L;;;;;N;;;;; +13113;EGYPTIAN HIEROGLYPH F020;Lo;0;L;;;;;N;;;;; +13114;EGYPTIAN HIEROGLYPH F021;Lo;0;L;;;;;N;;;;; +13115;EGYPTIAN HIEROGLYPH F021A;Lo;0;L;;;;;N;;;;; +13116;EGYPTIAN HIEROGLYPH F022;Lo;0;L;;;;;N;;;;; +13117;EGYPTIAN HIEROGLYPH F023;Lo;0;L;;;;;N;;;;; +13118;EGYPTIAN HIEROGLYPH F024;Lo;0;L;;;;;N;;;;; +13119;EGYPTIAN HIEROGLYPH F025;Lo;0;L;;;;;N;;;;; +1311A;EGYPTIAN HIEROGLYPH F026;Lo;0;L;;;;;N;;;;; +1311B;EGYPTIAN HIEROGLYPH F027;Lo;0;L;;;;;N;;;;; +1311C;EGYPTIAN HIEROGLYPH F028;Lo;0;L;;;;;N;;;;; +1311D;EGYPTIAN HIEROGLYPH F029;Lo;0;L;;;;;N;;;;; +1311E;EGYPTIAN HIEROGLYPH F030;Lo;0;L;;;;;N;;;;; +1311F;EGYPTIAN HIEROGLYPH F031;Lo;0;L;;;;;N;;;;; +13120;EGYPTIAN HIEROGLYPH F031A;Lo;0;L;;;;;N;;;;; +13121;EGYPTIAN HIEROGLYPH F032;Lo;0;L;;;;;N;;;;; +13122;EGYPTIAN HIEROGLYPH F033;Lo;0;L;;;;;N;;;;; +13123;EGYPTIAN HIEROGLYPH F034;Lo;0;L;;;;;N;;;;; +13124;EGYPTIAN HIEROGLYPH F035;Lo;0;L;;;;;N;;;;; +13125;EGYPTIAN HIEROGLYPH F036;Lo;0;L;;;;;N;;;;; +13126;EGYPTIAN HIEROGLYPH F037;Lo;0;L;;;;;N;;;;; +13127;EGYPTIAN HIEROGLYPH F037A;Lo;0;L;;;;;N;;;;; +13128;EGYPTIAN HIEROGLYPH F038;Lo;0;L;;;;;N;;;;; +13129;EGYPTIAN HIEROGLYPH F038A;Lo;0;L;;;;;N;;;;; +1312A;EGYPTIAN HIEROGLYPH F039;Lo;0;L;;;;;N;;;;; +1312B;EGYPTIAN HIEROGLYPH F040;Lo;0;L;;;;;N;;;;; +1312C;EGYPTIAN HIEROGLYPH F041;Lo;0;L;;;;;N;;;;; +1312D;EGYPTIAN HIEROGLYPH F042;Lo;0;L;;;;;N;;;;; +1312E;EGYPTIAN HIEROGLYPH F043;Lo;0;L;;;;;N;;;;; +1312F;EGYPTIAN HIEROGLYPH F044;Lo;0;L;;;;;N;;;;; +13130;EGYPTIAN HIEROGLYPH F045;Lo;0;L;;;;;N;;;;; +13131;EGYPTIAN HIEROGLYPH F045A;Lo;0;L;;;;;N;;;;; +13132;EGYPTIAN HIEROGLYPH F046;Lo;0;L;;;;;N;;;;; +13133;EGYPTIAN HIEROGLYPH F046A;Lo;0;L;;;;;N;;;;; +13134;EGYPTIAN HIEROGLYPH F047;Lo;0;L;;;;;N;;;;; +13135;EGYPTIAN HIEROGLYPH F047A;Lo;0;L;;;;;N;;;;; +13136;EGYPTIAN HIEROGLYPH F048;Lo;0;L;;;;;N;;;;; +13137;EGYPTIAN HIEROGLYPH F049;Lo;0;L;;;;;N;;;;; +13138;EGYPTIAN HIEROGLYPH F050;Lo;0;L;;;;;N;;;;; +13139;EGYPTIAN HIEROGLYPH F051;Lo;0;L;;;;;N;;;;; +1313A;EGYPTIAN HIEROGLYPH F051A;Lo;0;L;;;;;N;;;;; +1313B;EGYPTIAN HIEROGLYPH F051B;Lo;0;L;;;;;N;;;;; +1313C;EGYPTIAN HIEROGLYPH F051C;Lo;0;L;;;;;N;;;;; +1313D;EGYPTIAN HIEROGLYPH F052;Lo;0;L;;;;;N;;;;; +1313E;EGYPTIAN HIEROGLYPH F053;Lo;0;L;;;;;N;;;;; +1313F;EGYPTIAN HIEROGLYPH G001;Lo;0;L;;;;;N;;;;; +13140;EGYPTIAN HIEROGLYPH G002;Lo;0;L;;;;;N;;;;; +13141;EGYPTIAN HIEROGLYPH G003;Lo;0;L;;;;;N;;;;; +13142;EGYPTIAN HIEROGLYPH G004;Lo;0;L;;;;;N;;;;; +13143;EGYPTIAN HIEROGLYPH G005;Lo;0;L;;;;;N;;;;; +13144;EGYPTIAN HIEROGLYPH G006;Lo;0;L;;;;;N;;;;; +13145;EGYPTIAN HIEROGLYPH G006A;Lo;0;L;;;;;N;;;;; +13146;EGYPTIAN HIEROGLYPH G007;Lo;0;L;;;;;N;;;;; +13147;EGYPTIAN HIEROGLYPH G007A;Lo;0;L;;;;;N;;;;; +13148;EGYPTIAN HIEROGLYPH G007B;Lo;0;L;;;;;N;;;;; +13149;EGYPTIAN HIEROGLYPH G008;Lo;0;L;;;;;N;;;;; +1314A;EGYPTIAN HIEROGLYPH G009;Lo;0;L;;;;;N;;;;; +1314B;EGYPTIAN HIEROGLYPH G010;Lo;0;L;;;;;N;;;;; +1314C;EGYPTIAN HIEROGLYPH G011;Lo;0;L;;;;;N;;;;; +1314D;EGYPTIAN HIEROGLYPH G011A;Lo;0;L;;;;;N;;;;; +1314E;EGYPTIAN HIEROGLYPH G012;Lo;0;L;;;;;N;;;;; +1314F;EGYPTIAN HIEROGLYPH G013;Lo;0;L;;;;;N;;;;; +13150;EGYPTIAN HIEROGLYPH G014;Lo;0;L;;;;;N;;;;; +13151;EGYPTIAN HIEROGLYPH G015;Lo;0;L;;;;;N;;;;; +13152;EGYPTIAN HIEROGLYPH G016;Lo;0;L;;;;;N;;;;; +13153;EGYPTIAN HIEROGLYPH G017;Lo;0;L;;;;;N;;;;; +13154;EGYPTIAN HIEROGLYPH G018;Lo;0;L;;;;;N;;;;; +13155;EGYPTIAN HIEROGLYPH G019;Lo;0;L;;;;;N;;;;; +13156;EGYPTIAN HIEROGLYPH G020;Lo;0;L;;;;;N;;;;; +13157;EGYPTIAN HIEROGLYPH G020A;Lo;0;L;;;;;N;;;;; +13158;EGYPTIAN HIEROGLYPH G021;Lo;0;L;;;;;N;;;;; +13159;EGYPTIAN HIEROGLYPH G022;Lo;0;L;;;;;N;;;;; +1315A;EGYPTIAN HIEROGLYPH G023;Lo;0;L;;;;;N;;;;; +1315B;EGYPTIAN HIEROGLYPH G024;Lo;0;L;;;;;N;;;;; +1315C;EGYPTIAN HIEROGLYPH G025;Lo;0;L;;;;;N;;;;; +1315D;EGYPTIAN HIEROGLYPH G026;Lo;0;L;;;;;N;;;;; +1315E;EGYPTIAN HIEROGLYPH G026A;Lo;0;L;;;;;N;;;;; +1315F;EGYPTIAN HIEROGLYPH G027;Lo;0;L;;;;;N;;;;; +13160;EGYPTIAN HIEROGLYPH G028;Lo;0;L;;;;;N;;;;; +13161;EGYPTIAN HIEROGLYPH G029;Lo;0;L;;;;;N;;;;; +13162;EGYPTIAN HIEROGLYPH G030;Lo;0;L;;;;;N;;;;; +13163;EGYPTIAN HIEROGLYPH G031;Lo;0;L;;;;;N;;;;; +13164;EGYPTIAN HIEROGLYPH G032;Lo;0;L;;;;;N;;;;; +13165;EGYPTIAN HIEROGLYPH G033;Lo;0;L;;;;;N;;;;; +13166;EGYPTIAN HIEROGLYPH G034;Lo;0;L;;;;;N;;;;; +13167;EGYPTIAN HIEROGLYPH G035;Lo;0;L;;;;;N;;;;; +13168;EGYPTIAN HIEROGLYPH G036;Lo;0;L;;;;;N;;;;; +13169;EGYPTIAN HIEROGLYPH G036A;Lo;0;L;;;;;N;;;;; +1316A;EGYPTIAN HIEROGLYPH G037;Lo;0;L;;;;;N;;;;; +1316B;EGYPTIAN HIEROGLYPH G037A;Lo;0;L;;;;;N;;;;; +1316C;EGYPTIAN HIEROGLYPH G038;Lo;0;L;;;;;N;;;;; +1316D;EGYPTIAN HIEROGLYPH G039;Lo;0;L;;;;;N;;;;; +1316E;EGYPTIAN HIEROGLYPH G040;Lo;0;L;;;;;N;;;;; +1316F;EGYPTIAN HIEROGLYPH G041;Lo;0;L;;;;;N;;;;; +13170;EGYPTIAN HIEROGLYPH G042;Lo;0;L;;;;;N;;;;; +13171;EGYPTIAN HIEROGLYPH G043;Lo;0;L;;;;;N;;;;; +13172;EGYPTIAN HIEROGLYPH G043A;Lo;0;L;;;;;N;;;;; +13173;EGYPTIAN HIEROGLYPH G044;Lo;0;L;;;;;N;;;;; +13174;EGYPTIAN HIEROGLYPH G045;Lo;0;L;;;;;N;;;;; +13175;EGYPTIAN HIEROGLYPH G045A;Lo;0;L;;;;;N;;;;; +13176;EGYPTIAN HIEROGLYPH G046;Lo;0;L;;;;;N;;;;; +13177;EGYPTIAN HIEROGLYPH G047;Lo;0;L;;;;;N;;;;; +13178;EGYPTIAN HIEROGLYPH G048;Lo;0;L;;;;;N;;;;; +13179;EGYPTIAN HIEROGLYPH G049;Lo;0;L;;;;;N;;;;; +1317A;EGYPTIAN HIEROGLYPH G050;Lo;0;L;;;;;N;;;;; +1317B;EGYPTIAN HIEROGLYPH G051;Lo;0;L;;;;;N;;;;; +1317C;EGYPTIAN HIEROGLYPH G052;Lo;0;L;;;;;N;;;;; +1317D;EGYPTIAN HIEROGLYPH G053;Lo;0;L;;;;;N;;;;; +1317E;EGYPTIAN HIEROGLYPH G054;Lo;0;L;;;;;N;;;;; +1317F;EGYPTIAN HIEROGLYPH H001;Lo;0;L;;;;;N;;;;; +13180;EGYPTIAN HIEROGLYPH H002;Lo;0;L;;;;;N;;;;; +13181;EGYPTIAN HIEROGLYPH H003;Lo;0;L;;;;;N;;;;; +13182;EGYPTIAN HIEROGLYPH H004;Lo;0;L;;;;;N;;;;; +13183;EGYPTIAN HIEROGLYPH H005;Lo;0;L;;;;;N;;;;; +13184;EGYPTIAN HIEROGLYPH H006;Lo;0;L;;;;;N;;;;; +13185;EGYPTIAN HIEROGLYPH H006A;Lo;0;L;;;;;N;;;;; +13186;EGYPTIAN HIEROGLYPH H007;Lo;0;L;;;;;N;;;;; +13187;EGYPTIAN HIEROGLYPH H008;Lo;0;L;;;;;N;;;;; +13188;EGYPTIAN HIEROGLYPH I001;Lo;0;L;;;;;N;;;;; +13189;EGYPTIAN HIEROGLYPH I002;Lo;0;L;;;;;N;;;;; +1318A;EGYPTIAN HIEROGLYPH I003;Lo;0;L;;;;;N;;;;; +1318B;EGYPTIAN HIEROGLYPH I004;Lo;0;L;;;;;N;;;;; +1318C;EGYPTIAN HIEROGLYPH I005;Lo;0;L;;;;;N;;;;; +1318D;EGYPTIAN HIEROGLYPH I005A;Lo;0;L;;;;;N;;;;; +1318E;EGYPTIAN HIEROGLYPH I006;Lo;0;L;;;;;N;;;;; +1318F;EGYPTIAN HIEROGLYPH I007;Lo;0;L;;;;;N;;;;; +13190;EGYPTIAN HIEROGLYPH I008;Lo;0;L;;;;;N;;;;; +13191;EGYPTIAN HIEROGLYPH I009;Lo;0;L;;;;;N;;;;; +13192;EGYPTIAN HIEROGLYPH I009A;Lo;0;L;;;;;N;;;;; +13193;EGYPTIAN HIEROGLYPH I010;Lo;0;L;;;;;N;;;;; +13194;EGYPTIAN HIEROGLYPH I010A;Lo;0;L;;;;;N;;;;; +13195;EGYPTIAN HIEROGLYPH I011;Lo;0;L;;;;;N;;;;; +13196;EGYPTIAN HIEROGLYPH I011A;Lo;0;L;;;;;N;;;;; +13197;EGYPTIAN HIEROGLYPH I012;Lo;0;L;;;;;N;;;;; +13198;EGYPTIAN HIEROGLYPH I013;Lo;0;L;;;;;N;;;;; +13199;EGYPTIAN HIEROGLYPH I014;Lo;0;L;;;;;N;;;;; +1319A;EGYPTIAN HIEROGLYPH I015;Lo;0;L;;;;;N;;;;; +1319B;EGYPTIAN HIEROGLYPH K001;Lo;0;L;;;;;N;;;;; +1319C;EGYPTIAN HIEROGLYPH K002;Lo;0;L;;;;;N;;;;; +1319D;EGYPTIAN HIEROGLYPH K003;Lo;0;L;;;;;N;;;;; +1319E;EGYPTIAN HIEROGLYPH K004;Lo;0;L;;;;;N;;;;; +1319F;EGYPTIAN HIEROGLYPH K005;Lo;0;L;;;;;N;;;;; +131A0;EGYPTIAN HIEROGLYPH K006;Lo;0;L;;;;;N;;;;; +131A1;EGYPTIAN HIEROGLYPH K007;Lo;0;L;;;;;N;;;;; +131A2;EGYPTIAN HIEROGLYPH K008;Lo;0;L;;;;;N;;;;; +131A3;EGYPTIAN HIEROGLYPH L001;Lo;0;L;;;;;N;;;;; +131A4;EGYPTIAN HIEROGLYPH L002;Lo;0;L;;;;;N;;;;; +131A5;EGYPTIAN HIEROGLYPH L002A;Lo;0;L;;;;;N;;;;; +131A6;EGYPTIAN HIEROGLYPH L003;Lo;0;L;;;;;N;;;;; +131A7;EGYPTIAN HIEROGLYPH L004;Lo;0;L;;;;;N;;;;; +131A8;EGYPTIAN HIEROGLYPH L005;Lo;0;L;;;;;N;;;;; +131A9;EGYPTIAN HIEROGLYPH L006;Lo;0;L;;;;;N;;;;; +131AA;EGYPTIAN HIEROGLYPH L006A;Lo;0;L;;;;;N;;;;; +131AB;EGYPTIAN HIEROGLYPH L007;Lo;0;L;;;;;N;;;;; +131AC;EGYPTIAN HIEROGLYPH L008;Lo;0;L;;;;;N;;;;; +131AD;EGYPTIAN HIEROGLYPH M001;Lo;0;L;;;;;N;;;;; +131AE;EGYPTIAN HIEROGLYPH M001A;Lo;0;L;;;;;N;;;;; +131AF;EGYPTIAN HIEROGLYPH M001B;Lo;0;L;;;;;N;;;;; +131B0;EGYPTIAN HIEROGLYPH M002;Lo;0;L;;;;;N;;;;; +131B1;EGYPTIAN HIEROGLYPH M003;Lo;0;L;;;;;N;;;;; +131B2;EGYPTIAN HIEROGLYPH M003A;Lo;0;L;;;;;N;;;;; +131B3;EGYPTIAN HIEROGLYPH M004;Lo;0;L;;;;;N;;;;; +131B4;EGYPTIAN HIEROGLYPH M005;Lo;0;L;;;;;N;;;;; +131B5;EGYPTIAN HIEROGLYPH M006;Lo;0;L;;;;;N;;;;; +131B6;EGYPTIAN HIEROGLYPH M007;Lo;0;L;;;;;N;;;;; +131B7;EGYPTIAN HIEROGLYPH M008;Lo;0;L;;;;;N;;;;; +131B8;EGYPTIAN HIEROGLYPH M009;Lo;0;L;;;;;N;;;;; +131B9;EGYPTIAN HIEROGLYPH M010;Lo;0;L;;;;;N;;;;; +131BA;EGYPTIAN HIEROGLYPH M010A;Lo;0;L;;;;;N;;;;; +131BB;EGYPTIAN HIEROGLYPH M011;Lo;0;L;;;;;N;;;;; +131BC;EGYPTIAN HIEROGLYPH M012;Lo;0;L;;;;;N;;;;; +131BD;EGYPTIAN HIEROGLYPH M012A;Lo;0;L;;;;;N;;;;; +131BE;EGYPTIAN HIEROGLYPH M012B;Lo;0;L;;;;;N;;;;; +131BF;EGYPTIAN HIEROGLYPH M012C;Lo;0;L;;;;;N;;;;; +131C0;EGYPTIAN HIEROGLYPH M012D;Lo;0;L;;;;;N;;;;; +131C1;EGYPTIAN HIEROGLYPH M012E;Lo;0;L;;;;;N;;;;; +131C2;EGYPTIAN HIEROGLYPH M012F;Lo;0;L;;;;;N;;;;; +131C3;EGYPTIAN HIEROGLYPH M012G;Lo;0;L;;;;;N;;;;; +131C4;EGYPTIAN HIEROGLYPH M012H;Lo;0;L;;;;;N;;;;; +131C5;EGYPTIAN HIEROGLYPH M013;Lo;0;L;;;;;N;;;;; +131C6;EGYPTIAN HIEROGLYPH M014;Lo;0;L;;;;;N;;;;; +131C7;EGYPTIAN HIEROGLYPH M015;Lo;0;L;;;;;N;;;;; +131C8;EGYPTIAN HIEROGLYPH M015A;Lo;0;L;;;;;N;;;;; +131C9;EGYPTIAN HIEROGLYPH M016;Lo;0;L;;;;;N;;;;; +131CA;EGYPTIAN HIEROGLYPH M016A;Lo;0;L;;;;;N;;;;; +131CB;EGYPTIAN HIEROGLYPH M017;Lo;0;L;;;;;N;;;;; +131CC;EGYPTIAN HIEROGLYPH M017A;Lo;0;L;;;;;N;;;;; +131CD;EGYPTIAN HIEROGLYPH M018;Lo;0;L;;;;;N;;;;; +131CE;EGYPTIAN HIEROGLYPH M019;Lo;0;L;;;;;N;;;;; +131CF;EGYPTIAN HIEROGLYPH M020;Lo;0;L;;;;;N;;;;; +131D0;EGYPTIAN HIEROGLYPH M021;Lo;0;L;;;;;N;;;;; +131D1;EGYPTIAN HIEROGLYPH M022;Lo;0;L;;;;;N;;;;; +131D2;EGYPTIAN HIEROGLYPH M022A;Lo;0;L;;;;;N;;;;; +131D3;EGYPTIAN HIEROGLYPH M023;Lo;0;L;;;;;N;;;;; +131D4;EGYPTIAN HIEROGLYPH M024;Lo;0;L;;;;;N;;;;; +131D5;EGYPTIAN HIEROGLYPH M024A;Lo;0;L;;;;;N;;;;; +131D6;EGYPTIAN HIEROGLYPH M025;Lo;0;L;;;;;N;;;;; +131D7;EGYPTIAN HIEROGLYPH M026;Lo;0;L;;;;;N;;;;; +131D8;EGYPTIAN HIEROGLYPH M027;Lo;0;L;;;;;N;;;;; +131D9;EGYPTIAN HIEROGLYPH M028;Lo;0;L;;;;;N;;;;; +131DA;EGYPTIAN HIEROGLYPH M028A;Lo;0;L;;;;;N;;;;; +131DB;EGYPTIAN HIEROGLYPH M029;Lo;0;L;;;;;N;;;;; +131DC;EGYPTIAN HIEROGLYPH M030;Lo;0;L;;;;;N;;;;; +131DD;EGYPTIAN HIEROGLYPH M031;Lo;0;L;;;;;N;;;;; +131DE;EGYPTIAN HIEROGLYPH M031A;Lo;0;L;;;;;N;;;;; +131DF;EGYPTIAN HIEROGLYPH M032;Lo;0;L;;;;;N;;;;; +131E0;EGYPTIAN HIEROGLYPH M033;Lo;0;L;;;;;N;;;;; +131E1;EGYPTIAN HIEROGLYPH M033A;Lo;0;L;;;;;N;;;;; +131E2;EGYPTIAN HIEROGLYPH M033B;Lo;0;L;;;;;N;;;;; +131E3;EGYPTIAN HIEROGLYPH M034;Lo;0;L;;;;;N;;;;; +131E4;EGYPTIAN HIEROGLYPH M035;Lo;0;L;;;;;N;;;;; +131E5;EGYPTIAN HIEROGLYPH M036;Lo;0;L;;;;;N;;;;; +131E6;EGYPTIAN HIEROGLYPH M037;Lo;0;L;;;;;N;;;;; +131E7;EGYPTIAN HIEROGLYPH M038;Lo;0;L;;;;;N;;;;; +131E8;EGYPTIAN HIEROGLYPH M039;Lo;0;L;;;;;N;;;;; +131E9;EGYPTIAN HIEROGLYPH M040;Lo;0;L;;;;;N;;;;; +131EA;EGYPTIAN HIEROGLYPH M040A;Lo;0;L;;;;;N;;;;; +131EB;EGYPTIAN HIEROGLYPH M041;Lo;0;L;;;;;N;;;;; +131EC;EGYPTIAN HIEROGLYPH M042;Lo;0;L;;;;;N;;;;; +131ED;EGYPTIAN HIEROGLYPH M043;Lo;0;L;;;;;N;;;;; +131EE;EGYPTIAN HIEROGLYPH M044;Lo;0;L;;;;;N;;;;; +131EF;EGYPTIAN HIEROGLYPH N001;Lo;0;L;;;;;N;;;;; +131F0;EGYPTIAN HIEROGLYPH N002;Lo;0;L;;;;;N;;;;; +131F1;EGYPTIAN HIEROGLYPH N003;Lo;0;L;;;;;N;;;;; +131F2;EGYPTIAN HIEROGLYPH N004;Lo;0;L;;;;;N;;;;; +131F3;EGYPTIAN HIEROGLYPH N005;Lo;0;L;;;;;N;;;;; +131F4;EGYPTIAN HIEROGLYPH N006;Lo;0;L;;;;;N;;;;; +131F5;EGYPTIAN HIEROGLYPH N007;Lo;0;L;;;;;N;;;;; +131F6;EGYPTIAN HIEROGLYPH N008;Lo;0;L;;;;;N;;;;; +131F7;EGYPTIAN HIEROGLYPH N009;Lo;0;L;;;;;N;;;;; +131F8;EGYPTIAN HIEROGLYPH N010;Lo;0;L;;;;;N;;;;; +131F9;EGYPTIAN HIEROGLYPH N011;Lo;0;L;;;;;N;;;;; +131FA;EGYPTIAN HIEROGLYPH N012;Lo;0;L;;;;;N;;;;; +131FB;EGYPTIAN HIEROGLYPH N013;Lo;0;L;;;;;N;;;;; +131FC;EGYPTIAN HIEROGLYPH N014;Lo;0;L;;;;;N;;;;; +131FD;EGYPTIAN HIEROGLYPH N015;Lo;0;L;;;;;N;;;;; +131FE;EGYPTIAN HIEROGLYPH N016;Lo;0;L;;;;;N;;;;; +131FF;EGYPTIAN HIEROGLYPH N017;Lo;0;L;;;;;N;;;;; +13200;EGYPTIAN HIEROGLYPH N018;Lo;0;L;;;;;N;;;;; +13201;EGYPTIAN HIEROGLYPH N018A;Lo;0;L;;;;;N;;;;; +13202;EGYPTIAN HIEROGLYPH N018B;Lo;0;L;;;;;N;;;;; +13203;EGYPTIAN HIEROGLYPH N019;Lo;0;L;;;;;N;;;;; +13204;EGYPTIAN HIEROGLYPH N020;Lo;0;L;;;;;N;;;;; +13205;EGYPTIAN HIEROGLYPH N021;Lo;0;L;;;;;N;;;;; +13206;EGYPTIAN HIEROGLYPH N022;Lo;0;L;;;;;N;;;;; +13207;EGYPTIAN HIEROGLYPH N023;Lo;0;L;;;;;N;;;;; +13208;EGYPTIAN HIEROGLYPH N024;Lo;0;L;;;;;N;;;;; +13209;EGYPTIAN HIEROGLYPH N025;Lo;0;L;;;;;N;;;;; +1320A;EGYPTIAN HIEROGLYPH N025A;Lo;0;L;;;;;N;;;;; +1320B;EGYPTIAN HIEROGLYPH N026;Lo;0;L;;;;;N;;;;; +1320C;EGYPTIAN HIEROGLYPH N027;Lo;0;L;;;;;N;;;;; +1320D;EGYPTIAN HIEROGLYPH N028;Lo;0;L;;;;;N;;;;; +1320E;EGYPTIAN HIEROGLYPH N029;Lo;0;L;;;;;N;;;;; +1320F;EGYPTIAN HIEROGLYPH N030;Lo;0;L;;;;;N;;;;; +13210;EGYPTIAN HIEROGLYPH N031;Lo;0;L;;;;;N;;;;; +13211;EGYPTIAN HIEROGLYPH N032;Lo;0;L;;;;;N;;;;; +13212;EGYPTIAN HIEROGLYPH N033;Lo;0;L;;;;;N;;;;; +13213;EGYPTIAN HIEROGLYPH N033A;Lo;0;L;;;;;N;;;;; +13214;EGYPTIAN HIEROGLYPH N034;Lo;0;L;;;;;N;;;;; +13215;EGYPTIAN HIEROGLYPH N034A;Lo;0;L;;;;;N;;;;; +13216;EGYPTIAN HIEROGLYPH N035;Lo;0;L;;;;;N;;;;; +13217;EGYPTIAN HIEROGLYPH N035A;Lo;0;L;;;;;N;;;;; +13218;EGYPTIAN HIEROGLYPH N036;Lo;0;L;;;;;N;;;;; +13219;EGYPTIAN HIEROGLYPH N037;Lo;0;L;;;;;N;;;;; +1321A;EGYPTIAN HIEROGLYPH N037A;Lo;0;L;;;;;N;;;;; +1321B;EGYPTIAN HIEROGLYPH N038;Lo;0;L;;;;;N;;;;; +1321C;EGYPTIAN HIEROGLYPH N039;Lo;0;L;;;;;N;;;;; +1321D;EGYPTIAN HIEROGLYPH N040;Lo;0;L;;;;;N;;;;; +1321E;EGYPTIAN HIEROGLYPH N041;Lo;0;L;;;;;N;;;;; +1321F;EGYPTIAN HIEROGLYPH N042;Lo;0;L;;;;;N;;;;; +13220;EGYPTIAN HIEROGLYPH NL001;Lo;0;L;;;;;N;;;;; +13221;EGYPTIAN HIEROGLYPH NL002;Lo;0;L;;;;;N;;;;; +13222;EGYPTIAN HIEROGLYPH NL003;Lo;0;L;;;;;N;;;;; +13223;EGYPTIAN HIEROGLYPH NL004;Lo;0;L;;;;;N;;;;; +13224;EGYPTIAN HIEROGLYPH NL005;Lo;0;L;;;;;N;;;;; +13225;EGYPTIAN HIEROGLYPH NL005A;Lo;0;L;;;;;N;;;;; +13226;EGYPTIAN HIEROGLYPH NL006;Lo;0;L;;;;;N;;;;; +13227;EGYPTIAN HIEROGLYPH NL007;Lo;0;L;;;;;N;;;;; +13228;EGYPTIAN HIEROGLYPH NL008;Lo;0;L;;;;;N;;;;; +13229;EGYPTIAN HIEROGLYPH NL009;Lo;0;L;;;;;N;;;;; +1322A;EGYPTIAN HIEROGLYPH NL010;Lo;0;L;;;;;N;;;;; +1322B;EGYPTIAN HIEROGLYPH NL011;Lo;0;L;;;;;N;;;;; +1322C;EGYPTIAN HIEROGLYPH NL012;Lo;0;L;;;;;N;;;;; +1322D;EGYPTIAN HIEROGLYPH NL013;Lo;0;L;;;;;N;;;;; +1322E;EGYPTIAN HIEROGLYPH NL014;Lo;0;L;;;;;N;;;;; +1322F;EGYPTIAN HIEROGLYPH NL015;Lo;0;L;;;;;N;;;;; +13230;EGYPTIAN HIEROGLYPH NL016;Lo;0;L;;;;;N;;;;; +13231;EGYPTIAN HIEROGLYPH NL017;Lo;0;L;;;;;N;;;;; +13232;EGYPTIAN HIEROGLYPH NL017A;Lo;0;L;;;;;N;;;;; +13233;EGYPTIAN HIEROGLYPH NL018;Lo;0;L;;;;;N;;;;; +13234;EGYPTIAN HIEROGLYPH NL019;Lo;0;L;;;;;N;;;;; +13235;EGYPTIAN HIEROGLYPH NL020;Lo;0;L;;;;;N;;;;; +13236;EGYPTIAN HIEROGLYPH NU001;Lo;0;L;;;;;N;;;;; +13237;EGYPTIAN HIEROGLYPH NU002;Lo;0;L;;;;;N;;;;; +13238;EGYPTIAN HIEROGLYPH NU003;Lo;0;L;;;;;N;;;;; +13239;EGYPTIAN HIEROGLYPH NU004;Lo;0;L;;;;;N;;;;; +1323A;EGYPTIAN HIEROGLYPH NU005;Lo;0;L;;;;;N;;;;; +1323B;EGYPTIAN HIEROGLYPH NU006;Lo;0;L;;;;;N;;;;; +1323C;EGYPTIAN HIEROGLYPH NU007;Lo;0;L;;;;;N;;;;; +1323D;EGYPTIAN HIEROGLYPH NU008;Lo;0;L;;;;;N;;;;; +1323E;EGYPTIAN HIEROGLYPH NU009;Lo;0;L;;;;;N;;;;; +1323F;EGYPTIAN HIEROGLYPH NU010;Lo;0;L;;;;;N;;;;; +13240;EGYPTIAN HIEROGLYPH NU010A;Lo;0;L;;;;;N;;;;; +13241;EGYPTIAN HIEROGLYPH NU011;Lo;0;L;;;;;N;;;;; +13242;EGYPTIAN HIEROGLYPH NU011A;Lo;0;L;;;;;N;;;;; +13243;EGYPTIAN HIEROGLYPH NU012;Lo;0;L;;;;;N;;;;; +13244;EGYPTIAN HIEROGLYPH NU013;Lo;0;L;;;;;N;;;;; +13245;EGYPTIAN HIEROGLYPH NU014;Lo;0;L;;;;;N;;;;; +13246;EGYPTIAN HIEROGLYPH NU015;Lo;0;L;;;;;N;;;;; +13247;EGYPTIAN HIEROGLYPH NU016;Lo;0;L;;;;;N;;;;; +13248;EGYPTIAN HIEROGLYPH NU017;Lo;0;L;;;;;N;;;;; +13249;EGYPTIAN HIEROGLYPH NU018;Lo;0;L;;;;;N;;;;; +1324A;EGYPTIAN HIEROGLYPH NU018A;Lo;0;L;;;;;N;;;;; +1324B;EGYPTIAN HIEROGLYPH NU019;Lo;0;L;;;;;N;;;;; +1324C;EGYPTIAN HIEROGLYPH NU020;Lo;0;L;;;;;N;;;;; +1324D;EGYPTIAN HIEROGLYPH NU021;Lo;0;L;;;;;N;;;;; +1324E;EGYPTIAN HIEROGLYPH NU022;Lo;0;L;;;;;N;;;;; +1324F;EGYPTIAN HIEROGLYPH NU022A;Lo;0;L;;;;;N;;;;; +13250;EGYPTIAN HIEROGLYPH O001;Lo;0;L;;;;;N;;;;; +13251;EGYPTIAN HIEROGLYPH O001A;Lo;0;L;;;;;N;;;;; +13252;EGYPTIAN HIEROGLYPH O002;Lo;0;L;;;;;N;;;;; +13253;EGYPTIAN HIEROGLYPH O003;Lo;0;L;;;;;N;;;;; +13254;EGYPTIAN HIEROGLYPH O004;Lo;0;L;;;;;N;;;;; +13255;EGYPTIAN HIEROGLYPH O005;Lo;0;L;;;;;N;;;;; +13256;EGYPTIAN HIEROGLYPH O005A;Lo;0;L;;;;;N;;;;; +13257;EGYPTIAN HIEROGLYPH O006;Lo;0;L;;;;;N;;;;; +13258;EGYPTIAN HIEROGLYPH O006A;Lo;0;L;;;;;N;;;;; +13259;EGYPTIAN HIEROGLYPH O006B;Lo;0;L;;;;;N;;;;; +1325A;EGYPTIAN HIEROGLYPH O006C;Lo;0;L;;;;;N;;;;; +1325B;EGYPTIAN HIEROGLYPH O006D;Lo;0;L;;;;;N;;;;; +1325C;EGYPTIAN HIEROGLYPH O006E;Lo;0;L;;;;;N;;;;; +1325D;EGYPTIAN HIEROGLYPH O006F;Lo;0;L;;;;;N;;;;; +1325E;EGYPTIAN HIEROGLYPH O007;Lo;0;L;;;;;N;;;;; +1325F;EGYPTIAN HIEROGLYPH O008;Lo;0;L;;;;;N;;;;; +13260;EGYPTIAN HIEROGLYPH O009;Lo;0;L;;;;;N;;;;; +13261;EGYPTIAN HIEROGLYPH O010;Lo;0;L;;;;;N;;;;; +13262;EGYPTIAN HIEROGLYPH O010A;Lo;0;L;;;;;N;;;;; +13263;EGYPTIAN HIEROGLYPH O010B;Lo;0;L;;;;;N;;;;; +13264;EGYPTIAN HIEROGLYPH O010C;Lo;0;L;;;;;N;;;;; +13265;EGYPTIAN HIEROGLYPH O011;Lo;0;L;;;;;N;;;;; +13266;EGYPTIAN HIEROGLYPH O012;Lo;0;L;;;;;N;;;;; +13267;EGYPTIAN HIEROGLYPH O013;Lo;0;L;;;;;N;;;;; +13268;EGYPTIAN HIEROGLYPH O014;Lo;0;L;;;;;N;;;;; +13269;EGYPTIAN HIEROGLYPH O015;Lo;0;L;;;;;N;;;;; +1326A;EGYPTIAN HIEROGLYPH O016;Lo;0;L;;;;;N;;;;; +1326B;EGYPTIAN HIEROGLYPH O017;Lo;0;L;;;;;N;;;;; +1326C;EGYPTIAN HIEROGLYPH O018;Lo;0;L;;;;;N;;;;; +1326D;EGYPTIAN HIEROGLYPH O019;Lo;0;L;;;;;N;;;;; +1326E;EGYPTIAN HIEROGLYPH O019A;Lo;0;L;;;;;N;;;;; +1326F;EGYPTIAN HIEROGLYPH O020;Lo;0;L;;;;;N;;;;; +13270;EGYPTIAN HIEROGLYPH O020A;Lo;0;L;;;;;N;;;;; +13271;EGYPTIAN HIEROGLYPH O021;Lo;0;L;;;;;N;;;;; +13272;EGYPTIAN HIEROGLYPH O022;Lo;0;L;;;;;N;;;;; +13273;EGYPTIAN HIEROGLYPH O023;Lo;0;L;;;;;N;;;;; +13274;EGYPTIAN HIEROGLYPH O024;Lo;0;L;;;;;N;;;;; +13275;EGYPTIAN HIEROGLYPH O024A;Lo;0;L;;;;;N;;;;; +13276;EGYPTIAN HIEROGLYPH O025;Lo;0;L;;;;;N;;;;; +13277;EGYPTIAN HIEROGLYPH O025A;Lo;0;L;;;;;N;;;;; +13278;EGYPTIAN HIEROGLYPH O026;Lo;0;L;;;;;N;;;;; +13279;EGYPTIAN HIEROGLYPH O027;Lo;0;L;;;;;N;;;;; +1327A;EGYPTIAN HIEROGLYPH O028;Lo;0;L;;;;;N;;;;; +1327B;EGYPTIAN HIEROGLYPH O029;Lo;0;L;;;;;N;;;;; +1327C;EGYPTIAN HIEROGLYPH O029A;Lo;0;L;;;;;N;;;;; +1327D;EGYPTIAN HIEROGLYPH O030;Lo;0;L;;;;;N;;;;; +1327E;EGYPTIAN HIEROGLYPH O030A;Lo;0;L;;;;;N;;;;; +1327F;EGYPTIAN HIEROGLYPH O031;Lo;0;L;;;;;N;;;;; +13280;EGYPTIAN HIEROGLYPH O032;Lo;0;L;;;;;N;;;;; +13281;EGYPTIAN HIEROGLYPH O033;Lo;0;L;;;;;N;;;;; +13282;EGYPTIAN HIEROGLYPH O033A;Lo;0;L;;;;;N;;;;; +13283;EGYPTIAN HIEROGLYPH O034;Lo;0;L;;;;;N;;;;; +13284;EGYPTIAN HIEROGLYPH O035;Lo;0;L;;;;;N;;;;; +13285;EGYPTIAN HIEROGLYPH O036;Lo;0;L;;;;;N;;;;; +13286;EGYPTIAN HIEROGLYPH O036A;Lo;0;L;;;;;N;;;;; +13287;EGYPTIAN HIEROGLYPH O036B;Lo;0;L;;;;;N;;;;; +13288;EGYPTIAN HIEROGLYPH O036C;Lo;0;L;;;;;N;;;;; +13289;EGYPTIAN HIEROGLYPH O036D;Lo;0;L;;;;;N;;;;; +1328A;EGYPTIAN HIEROGLYPH O037;Lo;0;L;;;;;N;;;;; +1328B;EGYPTIAN HIEROGLYPH O038;Lo;0;L;;;;;N;;;;; +1328C;EGYPTIAN HIEROGLYPH O039;Lo;0;L;;;;;N;;;;; +1328D;EGYPTIAN HIEROGLYPH O040;Lo;0;L;;;;;N;;;;; +1328E;EGYPTIAN HIEROGLYPH O041;Lo;0;L;;;;;N;;;;; +1328F;EGYPTIAN HIEROGLYPH O042;Lo;0;L;;;;;N;;;;; +13290;EGYPTIAN HIEROGLYPH O043;Lo;0;L;;;;;N;;;;; +13291;EGYPTIAN HIEROGLYPH O044;Lo;0;L;;;;;N;;;;; +13292;EGYPTIAN HIEROGLYPH O045;Lo;0;L;;;;;N;;;;; +13293;EGYPTIAN HIEROGLYPH O046;Lo;0;L;;;;;N;;;;; +13294;EGYPTIAN HIEROGLYPH O047;Lo;0;L;;;;;N;;;;; +13295;EGYPTIAN HIEROGLYPH O048;Lo;0;L;;;;;N;;;;; +13296;EGYPTIAN HIEROGLYPH O049;Lo;0;L;;;;;N;;;;; +13297;EGYPTIAN HIEROGLYPH O050;Lo;0;L;;;;;N;;;;; +13298;EGYPTIAN HIEROGLYPH O050A;Lo;0;L;;;;;N;;;;; +13299;EGYPTIAN HIEROGLYPH O050B;Lo;0;L;;;;;N;;;;; +1329A;EGYPTIAN HIEROGLYPH O051;Lo;0;L;;;;;N;;;;; +1329B;EGYPTIAN HIEROGLYPH P001;Lo;0;L;;;;;N;;;;; +1329C;EGYPTIAN HIEROGLYPH P001A;Lo;0;L;;;;;N;;;;; +1329D;EGYPTIAN HIEROGLYPH P002;Lo;0;L;;;;;N;;;;; +1329E;EGYPTIAN HIEROGLYPH P003;Lo;0;L;;;;;N;;;;; +1329F;EGYPTIAN HIEROGLYPH P003A;Lo;0;L;;;;;N;;;;; +132A0;EGYPTIAN HIEROGLYPH P004;Lo;0;L;;;;;N;;;;; +132A1;EGYPTIAN HIEROGLYPH P005;Lo;0;L;;;;;N;;;;; +132A2;EGYPTIAN HIEROGLYPH P006;Lo;0;L;;;;;N;;;;; +132A3;EGYPTIAN HIEROGLYPH P007;Lo;0;L;;;;;N;;;;; +132A4;EGYPTIAN HIEROGLYPH P008;Lo;0;L;;;;;N;;;;; +132A5;EGYPTIAN HIEROGLYPH P009;Lo;0;L;;;;;N;;;;; +132A6;EGYPTIAN HIEROGLYPH P010;Lo;0;L;;;;;N;;;;; +132A7;EGYPTIAN HIEROGLYPH P011;Lo;0;L;;;;;N;;;;; +132A8;EGYPTIAN HIEROGLYPH Q001;Lo;0;L;;;;;N;;;;; +132A9;EGYPTIAN HIEROGLYPH Q002;Lo;0;L;;;;;N;;;;; +132AA;EGYPTIAN HIEROGLYPH Q003;Lo;0;L;;;;;N;;;;; +132AB;EGYPTIAN HIEROGLYPH Q004;Lo;0;L;;;;;N;;;;; +132AC;EGYPTIAN HIEROGLYPH Q005;Lo;0;L;;;;;N;;;;; +132AD;EGYPTIAN HIEROGLYPH Q006;Lo;0;L;;;;;N;;;;; +132AE;EGYPTIAN HIEROGLYPH Q007;Lo;0;L;;;;;N;;;;; +132AF;EGYPTIAN HIEROGLYPH R001;Lo;0;L;;;;;N;;;;; +132B0;EGYPTIAN HIEROGLYPH R002;Lo;0;L;;;;;N;;;;; +132B1;EGYPTIAN HIEROGLYPH R002A;Lo;0;L;;;;;N;;;;; +132B2;EGYPTIAN HIEROGLYPH R003;Lo;0;L;;;;;N;;;;; +132B3;EGYPTIAN HIEROGLYPH R003A;Lo;0;L;;;;;N;;;;; +132B4;EGYPTIAN HIEROGLYPH R003B;Lo;0;L;;;;;N;;;;; +132B5;EGYPTIAN HIEROGLYPH R004;Lo;0;L;;;;;N;;;;; +132B6;EGYPTIAN HIEROGLYPH R005;Lo;0;L;;;;;N;;;;; +132B7;EGYPTIAN HIEROGLYPH R006;Lo;0;L;;;;;N;;;;; +132B8;EGYPTIAN HIEROGLYPH R007;Lo;0;L;;;;;N;;;;; +132B9;EGYPTIAN HIEROGLYPH R008;Lo;0;L;;;;;N;;;;; +132BA;EGYPTIAN HIEROGLYPH R009;Lo;0;L;;;;;N;;;;; +132BB;EGYPTIAN HIEROGLYPH R010;Lo;0;L;;;;;N;;;;; +132BC;EGYPTIAN HIEROGLYPH R010A;Lo;0;L;;;;;N;;;;; +132BD;EGYPTIAN HIEROGLYPH R011;Lo;0;L;;;;;N;;;;; +132BE;EGYPTIAN HIEROGLYPH R012;Lo;0;L;;;;;N;;;;; +132BF;EGYPTIAN HIEROGLYPH R013;Lo;0;L;;;;;N;;;;; +132C0;EGYPTIAN HIEROGLYPH R014;Lo;0;L;;;;;N;;;;; +132C1;EGYPTIAN HIEROGLYPH R015;Lo;0;L;;;;;N;;;;; +132C2;EGYPTIAN HIEROGLYPH R016;Lo;0;L;;;;;N;;;;; +132C3;EGYPTIAN HIEROGLYPH R016A;Lo;0;L;;;;;N;;;;; +132C4;EGYPTIAN HIEROGLYPH R017;Lo;0;L;;;;;N;;;;; +132C5;EGYPTIAN HIEROGLYPH R018;Lo;0;L;;;;;N;;;;; +132C6;EGYPTIAN HIEROGLYPH R019;Lo;0;L;;;;;N;;;;; +132C7;EGYPTIAN HIEROGLYPH R020;Lo;0;L;;;;;N;;;;; +132C8;EGYPTIAN HIEROGLYPH R021;Lo;0;L;;;;;N;;;;; +132C9;EGYPTIAN HIEROGLYPH R022;Lo;0;L;;;;;N;;;;; +132CA;EGYPTIAN HIEROGLYPH R023;Lo;0;L;;;;;N;;;;; +132CB;EGYPTIAN HIEROGLYPH R024;Lo;0;L;;;;;N;;;;; +132CC;EGYPTIAN HIEROGLYPH R025;Lo;0;L;;;;;N;;;;; +132CD;EGYPTIAN HIEROGLYPH R026;Lo;0;L;;;;;N;;;;; +132CE;EGYPTIAN HIEROGLYPH R027;Lo;0;L;;;;;N;;;;; +132CF;EGYPTIAN HIEROGLYPH R028;Lo;0;L;;;;;N;;;;; +132D0;EGYPTIAN HIEROGLYPH R029;Lo;0;L;;;;;N;;;;; +132D1;EGYPTIAN HIEROGLYPH S001;Lo;0;L;;;;;N;;;;; +132D2;EGYPTIAN HIEROGLYPH S002;Lo;0;L;;;;;N;;;;; +132D3;EGYPTIAN HIEROGLYPH S002A;Lo;0;L;;;;;N;;;;; +132D4;EGYPTIAN HIEROGLYPH S003;Lo;0;L;;;;;N;;;;; +132D5;EGYPTIAN HIEROGLYPH S004;Lo;0;L;;;;;N;;;;; +132D6;EGYPTIAN HIEROGLYPH S005;Lo;0;L;;;;;N;;;;; +132D7;EGYPTIAN HIEROGLYPH S006;Lo;0;L;;;;;N;;;;; +132D8;EGYPTIAN HIEROGLYPH S006A;Lo;0;L;;;;;N;;;;; +132D9;EGYPTIAN HIEROGLYPH S007;Lo;0;L;;;;;N;;;;; +132DA;EGYPTIAN HIEROGLYPH S008;Lo;0;L;;;;;N;;;;; +132DB;EGYPTIAN HIEROGLYPH S009;Lo;0;L;;;;;N;;;;; +132DC;EGYPTIAN HIEROGLYPH S010;Lo;0;L;;;;;N;;;;; +132DD;EGYPTIAN HIEROGLYPH S011;Lo;0;L;;;;;N;;;;; +132DE;EGYPTIAN HIEROGLYPH S012;Lo;0;L;;;;;N;;;;; +132DF;EGYPTIAN HIEROGLYPH S013;Lo;0;L;;;;;N;;;;; +132E0;EGYPTIAN HIEROGLYPH S014;Lo;0;L;;;;;N;;;;; +132E1;EGYPTIAN HIEROGLYPH S014A;Lo;0;L;;;;;N;;;;; +132E2;EGYPTIAN HIEROGLYPH S014B;Lo;0;L;;;;;N;;;;; +132E3;EGYPTIAN HIEROGLYPH S015;Lo;0;L;;;;;N;;;;; +132E4;EGYPTIAN HIEROGLYPH S016;Lo;0;L;;;;;N;;;;; +132E5;EGYPTIAN HIEROGLYPH S017;Lo;0;L;;;;;N;;;;; +132E6;EGYPTIAN HIEROGLYPH S017A;Lo;0;L;;;;;N;;;;; +132E7;EGYPTIAN HIEROGLYPH S018;Lo;0;L;;;;;N;;;;; +132E8;EGYPTIAN HIEROGLYPH S019;Lo;0;L;;;;;N;;;;; +132E9;EGYPTIAN HIEROGLYPH S020;Lo;0;L;;;;;N;;;;; +132EA;EGYPTIAN HIEROGLYPH S021;Lo;0;L;;;;;N;;;;; +132EB;EGYPTIAN HIEROGLYPH S022;Lo;0;L;;;;;N;;;;; +132EC;EGYPTIAN HIEROGLYPH S023;Lo;0;L;;;;;N;;;;; +132ED;EGYPTIAN HIEROGLYPH S024;Lo;0;L;;;;;N;;;;; +132EE;EGYPTIAN HIEROGLYPH S025;Lo;0;L;;;;;N;;;;; +132EF;EGYPTIAN HIEROGLYPH S026;Lo;0;L;;;;;N;;;;; +132F0;EGYPTIAN HIEROGLYPH S026A;Lo;0;L;;;;;N;;;;; +132F1;EGYPTIAN HIEROGLYPH S026B;Lo;0;L;;;;;N;;;;; +132F2;EGYPTIAN HIEROGLYPH S027;Lo;0;L;;;;;N;;;;; +132F3;EGYPTIAN HIEROGLYPH S028;Lo;0;L;;;;;N;;;;; +132F4;EGYPTIAN HIEROGLYPH S029;Lo;0;L;;;;;N;;;;; +132F5;EGYPTIAN HIEROGLYPH S030;Lo;0;L;;;;;N;;;;; +132F6;EGYPTIAN HIEROGLYPH S031;Lo;0;L;;;;;N;;;;; +132F7;EGYPTIAN HIEROGLYPH S032;Lo;0;L;;;;;N;;;;; +132F8;EGYPTIAN HIEROGLYPH S033;Lo;0;L;;;;;N;;;;; +132F9;EGYPTIAN HIEROGLYPH S034;Lo;0;L;;;;;N;;;;; +132FA;EGYPTIAN HIEROGLYPH S035;Lo;0;L;;;;;N;;;;; +132FB;EGYPTIAN HIEROGLYPH S035A;Lo;0;L;;;;;N;;;;; +132FC;EGYPTIAN HIEROGLYPH S036;Lo;0;L;;;;;N;;;;; +132FD;EGYPTIAN HIEROGLYPH S037;Lo;0;L;;;;;N;;;;; +132FE;EGYPTIAN HIEROGLYPH S038;Lo;0;L;;;;;N;;;;; +132FF;EGYPTIAN HIEROGLYPH S039;Lo;0;L;;;;;N;;;;; +13300;EGYPTIAN HIEROGLYPH S040;Lo;0;L;;;;;N;;;;; +13301;EGYPTIAN HIEROGLYPH S041;Lo;0;L;;;;;N;;;;; +13302;EGYPTIAN HIEROGLYPH S042;Lo;0;L;;;;;N;;;;; +13303;EGYPTIAN HIEROGLYPH S043;Lo;0;L;;;;;N;;;;; +13304;EGYPTIAN HIEROGLYPH S044;Lo;0;L;;;;;N;;;;; +13305;EGYPTIAN HIEROGLYPH S045;Lo;0;L;;;;;N;;;;; +13306;EGYPTIAN HIEROGLYPH S046;Lo;0;L;;;;;N;;;;; +13307;EGYPTIAN HIEROGLYPH T001;Lo;0;L;;;;;N;;;;; +13308;EGYPTIAN HIEROGLYPH T002;Lo;0;L;;;;;N;;;;; +13309;EGYPTIAN HIEROGLYPH T003;Lo;0;L;;;;;N;;;;; +1330A;EGYPTIAN HIEROGLYPH T003A;Lo;0;L;;;;;N;;;;; +1330B;EGYPTIAN HIEROGLYPH T004;Lo;0;L;;;;;N;;;;; +1330C;EGYPTIAN HIEROGLYPH T005;Lo;0;L;;;;;N;;;;; +1330D;EGYPTIAN HIEROGLYPH T006;Lo;0;L;;;;;N;;;;; +1330E;EGYPTIAN HIEROGLYPH T007;Lo;0;L;;;;;N;;;;; +1330F;EGYPTIAN HIEROGLYPH T007A;Lo;0;L;;;;;N;;;;; +13310;EGYPTIAN HIEROGLYPH T008;Lo;0;L;;;;;N;;;;; +13311;EGYPTIAN HIEROGLYPH T008A;Lo;0;L;;;;;N;;;;; +13312;EGYPTIAN HIEROGLYPH T009;Lo;0;L;;;;;N;;;;; +13313;EGYPTIAN HIEROGLYPH T009A;Lo;0;L;;;;;N;;;;; +13314;EGYPTIAN HIEROGLYPH T010;Lo;0;L;;;;;N;;;;; +13315;EGYPTIAN HIEROGLYPH T011;Lo;0;L;;;;;N;;;;; +13316;EGYPTIAN HIEROGLYPH T011A;Lo;0;L;;;;;N;;;;; +13317;EGYPTIAN HIEROGLYPH T012;Lo;0;L;;;;;N;;;;; +13318;EGYPTIAN HIEROGLYPH T013;Lo;0;L;;;;;N;;;;; +13319;EGYPTIAN HIEROGLYPH T014;Lo;0;L;;;;;N;;;;; +1331A;EGYPTIAN HIEROGLYPH T015;Lo;0;L;;;;;N;;;;; +1331B;EGYPTIAN HIEROGLYPH T016;Lo;0;L;;;;;N;;;;; +1331C;EGYPTIAN HIEROGLYPH T016A;Lo;0;L;;;;;N;;;;; +1331D;EGYPTIAN HIEROGLYPH T017;Lo;0;L;;;;;N;;;;; +1331E;EGYPTIAN HIEROGLYPH T018;Lo;0;L;;;;;N;;;;; +1331F;EGYPTIAN HIEROGLYPH T019;Lo;0;L;;;;;N;;;;; +13320;EGYPTIAN HIEROGLYPH T020;Lo;0;L;;;;;N;;;;; +13321;EGYPTIAN HIEROGLYPH T021;Lo;0;L;;;;;N;;;;; +13322;EGYPTIAN HIEROGLYPH T022;Lo;0;L;;;;;N;;;;; +13323;EGYPTIAN HIEROGLYPH T023;Lo;0;L;;;;;N;;;;; +13324;EGYPTIAN HIEROGLYPH T024;Lo;0;L;;;;;N;;;;; +13325;EGYPTIAN HIEROGLYPH T025;Lo;0;L;;;;;N;;;;; +13326;EGYPTIAN HIEROGLYPH T026;Lo;0;L;;;;;N;;;;; +13327;EGYPTIAN HIEROGLYPH T027;Lo;0;L;;;;;N;;;;; +13328;EGYPTIAN HIEROGLYPH T028;Lo;0;L;;;;;N;;;;; +13329;EGYPTIAN HIEROGLYPH T029;Lo;0;L;;;;;N;;;;; +1332A;EGYPTIAN HIEROGLYPH T030;Lo;0;L;;;;;N;;;;; +1332B;EGYPTIAN HIEROGLYPH T031;Lo;0;L;;;;;N;;;;; +1332C;EGYPTIAN HIEROGLYPH T032;Lo;0;L;;;;;N;;;;; +1332D;EGYPTIAN HIEROGLYPH T032A;Lo;0;L;;;;;N;;;;; +1332E;EGYPTIAN HIEROGLYPH T033;Lo;0;L;;;;;N;;;;; +1332F;EGYPTIAN HIEROGLYPH T033A;Lo;0;L;;;;;N;;;;; +13330;EGYPTIAN HIEROGLYPH T034;Lo;0;L;;;;;N;;;;; +13331;EGYPTIAN HIEROGLYPH T035;Lo;0;L;;;;;N;;;;; +13332;EGYPTIAN HIEROGLYPH T036;Lo;0;L;;;;;N;;;;; +13333;EGYPTIAN HIEROGLYPH U001;Lo;0;L;;;;;N;;;;; +13334;EGYPTIAN HIEROGLYPH U002;Lo;0;L;;;;;N;;;;; +13335;EGYPTIAN HIEROGLYPH U003;Lo;0;L;;;;;N;;;;; +13336;EGYPTIAN HIEROGLYPH U004;Lo;0;L;;;;;N;;;;; +13337;EGYPTIAN HIEROGLYPH U005;Lo;0;L;;;;;N;;;;; +13338;EGYPTIAN HIEROGLYPH U006;Lo;0;L;;;;;N;;;;; +13339;EGYPTIAN HIEROGLYPH U006A;Lo;0;L;;;;;N;;;;; +1333A;EGYPTIAN HIEROGLYPH U006B;Lo;0;L;;;;;N;;;;; +1333B;EGYPTIAN HIEROGLYPH U007;Lo;0;L;;;;;N;;;;; +1333C;EGYPTIAN HIEROGLYPH U008;Lo;0;L;;;;;N;;;;; +1333D;EGYPTIAN HIEROGLYPH U009;Lo;0;L;;;;;N;;;;; +1333E;EGYPTIAN HIEROGLYPH U010;Lo;0;L;;;;;N;;;;; +1333F;EGYPTIAN HIEROGLYPH U011;Lo;0;L;;;;;N;;;;; +13340;EGYPTIAN HIEROGLYPH U012;Lo;0;L;;;;;N;;;;; +13341;EGYPTIAN HIEROGLYPH U013;Lo;0;L;;;;;N;;;;; +13342;EGYPTIAN HIEROGLYPH U014;Lo;0;L;;;;;N;;;;; +13343;EGYPTIAN HIEROGLYPH U015;Lo;0;L;;;;;N;;;;; +13344;EGYPTIAN HIEROGLYPH U016;Lo;0;L;;;;;N;;;;; +13345;EGYPTIAN HIEROGLYPH U017;Lo;0;L;;;;;N;;;;; +13346;EGYPTIAN HIEROGLYPH U018;Lo;0;L;;;;;N;;;;; +13347;EGYPTIAN HIEROGLYPH U019;Lo;0;L;;;;;N;;;;; +13348;EGYPTIAN HIEROGLYPH U020;Lo;0;L;;;;;N;;;;; +13349;EGYPTIAN HIEROGLYPH U021;Lo;0;L;;;;;N;;;;; +1334A;EGYPTIAN HIEROGLYPH U022;Lo;0;L;;;;;N;;;;; +1334B;EGYPTIAN HIEROGLYPH U023;Lo;0;L;;;;;N;;;;; +1334C;EGYPTIAN HIEROGLYPH U023A;Lo;0;L;;;;;N;;;;; +1334D;EGYPTIAN HIEROGLYPH U024;Lo;0;L;;;;;N;;;;; +1334E;EGYPTIAN HIEROGLYPH U025;Lo;0;L;;;;;N;;;;; +1334F;EGYPTIAN HIEROGLYPH U026;Lo;0;L;;;;;N;;;;; +13350;EGYPTIAN HIEROGLYPH U027;Lo;0;L;;;;;N;;;;; +13351;EGYPTIAN HIEROGLYPH U028;Lo;0;L;;;;;N;;;;; +13352;EGYPTIAN HIEROGLYPH U029;Lo;0;L;;;;;N;;;;; +13353;EGYPTIAN HIEROGLYPH U029A;Lo;0;L;;;;;N;;;;; +13354;EGYPTIAN HIEROGLYPH U030;Lo;0;L;;;;;N;;;;; +13355;EGYPTIAN HIEROGLYPH U031;Lo;0;L;;;;;N;;;;; +13356;EGYPTIAN HIEROGLYPH U032;Lo;0;L;;;;;N;;;;; +13357;EGYPTIAN HIEROGLYPH U032A;Lo;0;L;;;;;N;;;;; +13358;EGYPTIAN HIEROGLYPH U033;Lo;0;L;;;;;N;;;;; +13359;EGYPTIAN HIEROGLYPH U034;Lo;0;L;;;;;N;;;;; +1335A;EGYPTIAN HIEROGLYPH U035;Lo;0;L;;;;;N;;;;; +1335B;EGYPTIAN HIEROGLYPH U036;Lo;0;L;;;;;N;;;;; +1335C;EGYPTIAN HIEROGLYPH U037;Lo;0;L;;;;;N;;;;; +1335D;EGYPTIAN HIEROGLYPH U038;Lo;0;L;;;;;N;;;;; +1335E;EGYPTIAN HIEROGLYPH U039;Lo;0;L;;;;;N;;;;; +1335F;EGYPTIAN HIEROGLYPH U040;Lo;0;L;;;;;N;;;;; +13360;EGYPTIAN HIEROGLYPH U041;Lo;0;L;;;;;N;;;;; +13361;EGYPTIAN HIEROGLYPH U042;Lo;0;L;;;;;N;;;;; +13362;EGYPTIAN HIEROGLYPH V001;Lo;0;L;;;;;N;;;;; +13363;EGYPTIAN HIEROGLYPH V001A;Lo;0;L;;;;;N;;;;; +13364;EGYPTIAN HIEROGLYPH V001B;Lo;0;L;;;;;N;;;;; +13365;EGYPTIAN HIEROGLYPH V001C;Lo;0;L;;;;;N;;;;; +13366;EGYPTIAN HIEROGLYPH V001D;Lo;0;L;;;;;N;;;;; +13367;EGYPTIAN HIEROGLYPH V001E;Lo;0;L;;;;;N;;;;; +13368;EGYPTIAN HIEROGLYPH V001F;Lo;0;L;;;;;N;;;;; +13369;EGYPTIAN HIEROGLYPH V001G;Lo;0;L;;;;;N;;;;; +1336A;EGYPTIAN HIEROGLYPH V001H;Lo;0;L;;;;;N;;;;; +1336B;EGYPTIAN HIEROGLYPH V001I;Lo;0;L;;;;;N;;;;; +1336C;EGYPTIAN HIEROGLYPH V002;Lo;0;L;;;;;N;;;;; +1336D;EGYPTIAN HIEROGLYPH V002A;Lo;0;L;;;;;N;;;;; +1336E;EGYPTIAN HIEROGLYPH V003;Lo;0;L;;;;;N;;;;; +1336F;EGYPTIAN HIEROGLYPH V004;Lo;0;L;;;;;N;;;;; +13370;EGYPTIAN HIEROGLYPH V005;Lo;0;L;;;;;N;;;;; +13371;EGYPTIAN HIEROGLYPH V006;Lo;0;L;;;;;N;;;;; +13372;EGYPTIAN HIEROGLYPH V007;Lo;0;L;;;;;N;;;;; +13373;EGYPTIAN HIEROGLYPH V007A;Lo;0;L;;;;;N;;;;; +13374;EGYPTIAN HIEROGLYPH V007B;Lo;0;L;;;;;N;;;;; +13375;EGYPTIAN HIEROGLYPH V008;Lo;0;L;;;;;N;;;;; +13376;EGYPTIAN HIEROGLYPH V009;Lo;0;L;;;;;N;;;;; +13377;EGYPTIAN HIEROGLYPH V010;Lo;0;L;;;;;N;;;;; +13378;EGYPTIAN HIEROGLYPH V011;Lo;0;L;;;;;N;;;;; +13379;EGYPTIAN HIEROGLYPH V011A;Lo;0;L;;;;;N;;;;; +1337A;EGYPTIAN HIEROGLYPH V011B;Lo;0;L;;;;;N;;;;; +1337B;EGYPTIAN HIEROGLYPH V011C;Lo;0;L;;;;;N;;;;; +1337C;EGYPTIAN HIEROGLYPH V012;Lo;0;L;;;;;N;;;;; +1337D;EGYPTIAN HIEROGLYPH V012A;Lo;0;L;;;;;N;;;;; +1337E;EGYPTIAN HIEROGLYPH V012B;Lo;0;L;;;;;N;;;;; +1337F;EGYPTIAN HIEROGLYPH V013;Lo;0;L;;;;;N;;;;; +13380;EGYPTIAN HIEROGLYPH V014;Lo;0;L;;;;;N;;;;; +13381;EGYPTIAN HIEROGLYPH V015;Lo;0;L;;;;;N;;;;; +13382;EGYPTIAN HIEROGLYPH V016;Lo;0;L;;;;;N;;;;; +13383;EGYPTIAN HIEROGLYPH V017;Lo;0;L;;;;;N;;;;; +13384;EGYPTIAN HIEROGLYPH V018;Lo;0;L;;;;;N;;;;; +13385;EGYPTIAN HIEROGLYPH V019;Lo;0;L;;;;;N;;;;; +13386;EGYPTIAN HIEROGLYPH V020;Lo;0;L;;;;;N;;;;; +13387;EGYPTIAN HIEROGLYPH V020A;Lo;0;L;;;;;N;;;;; +13388;EGYPTIAN HIEROGLYPH V020B;Lo;0;L;;;;;N;;;;; +13389;EGYPTIAN HIEROGLYPH V020C;Lo;0;L;;;;;N;;;;; +1338A;EGYPTIAN HIEROGLYPH V020D;Lo;0;L;;;;;N;;;;; +1338B;EGYPTIAN HIEROGLYPH V020E;Lo;0;L;;;;;N;;;;; +1338C;EGYPTIAN HIEROGLYPH V020F;Lo;0;L;;;;;N;;;;; +1338D;EGYPTIAN HIEROGLYPH V020G;Lo;0;L;;;;;N;;;;; +1338E;EGYPTIAN HIEROGLYPH V020H;Lo;0;L;;;;;N;;;;; +1338F;EGYPTIAN HIEROGLYPH V020I;Lo;0;L;;;;;N;;;;; +13390;EGYPTIAN HIEROGLYPH V020J;Lo;0;L;;;;;N;;;;; +13391;EGYPTIAN HIEROGLYPH V020K;Lo;0;L;;;;;N;;;;; +13392;EGYPTIAN HIEROGLYPH V020L;Lo;0;L;;;;;N;;;;; +13393;EGYPTIAN HIEROGLYPH V021;Lo;0;L;;;;;N;;;;; +13394;EGYPTIAN HIEROGLYPH V022;Lo;0;L;;;;;N;;;;; +13395;EGYPTIAN HIEROGLYPH V023;Lo;0;L;;;;;N;;;;; +13396;EGYPTIAN HIEROGLYPH V023A;Lo;0;L;;;;;N;;;;; +13397;EGYPTIAN HIEROGLYPH V024;Lo;0;L;;;;;N;;;;; +13398;EGYPTIAN HIEROGLYPH V025;Lo;0;L;;;;;N;;;;; +13399;EGYPTIAN HIEROGLYPH V026;Lo;0;L;;;;;N;;;;; +1339A;EGYPTIAN HIEROGLYPH V027;Lo;0;L;;;;;N;;;;; +1339B;EGYPTIAN HIEROGLYPH V028;Lo;0;L;;;;;N;;;;; +1339C;EGYPTIAN HIEROGLYPH V028A;Lo;0;L;;;;;N;;;;; +1339D;EGYPTIAN HIEROGLYPH V029;Lo;0;L;;;;;N;;;;; +1339E;EGYPTIAN HIEROGLYPH V029A;Lo;0;L;;;;;N;;;;; +1339F;EGYPTIAN HIEROGLYPH V030;Lo;0;L;;;;;N;;;;; +133A0;EGYPTIAN HIEROGLYPH V030A;Lo;0;L;;;;;N;;;;; +133A1;EGYPTIAN HIEROGLYPH V031;Lo;0;L;;;;;N;;;;; +133A2;EGYPTIAN HIEROGLYPH V031A;Lo;0;L;;;;;N;;;;; +133A3;EGYPTIAN HIEROGLYPH V032;Lo;0;L;;;;;N;;;;; +133A4;EGYPTIAN HIEROGLYPH V033;Lo;0;L;;;;;N;;;;; +133A5;EGYPTIAN HIEROGLYPH V033A;Lo;0;L;;;;;N;;;;; +133A6;EGYPTIAN HIEROGLYPH V034;Lo;0;L;;;;;N;;;;; +133A7;EGYPTIAN HIEROGLYPH V035;Lo;0;L;;;;;N;;;;; +133A8;EGYPTIAN HIEROGLYPH V036;Lo;0;L;;;;;N;;;;; +133A9;EGYPTIAN HIEROGLYPH V037;Lo;0;L;;;;;N;;;;; +133AA;EGYPTIAN HIEROGLYPH V037A;Lo;0;L;;;;;N;;;;; +133AB;EGYPTIAN HIEROGLYPH V038;Lo;0;L;;;;;N;;;;; +133AC;EGYPTIAN HIEROGLYPH V039;Lo;0;L;;;;;N;;;;; +133AD;EGYPTIAN HIEROGLYPH V040;Lo;0;L;;;;;N;;;;; +133AE;EGYPTIAN HIEROGLYPH V040A;Lo;0;L;;;;;N;;;;; +133AF;EGYPTIAN HIEROGLYPH W001;Lo;0;L;;;;;N;;;;; +133B0;EGYPTIAN HIEROGLYPH W002;Lo;0;L;;;;;N;;;;; +133B1;EGYPTIAN HIEROGLYPH W003;Lo;0;L;;;;;N;;;;; +133B2;EGYPTIAN HIEROGLYPH W003A;Lo;0;L;;;;;N;;;;; +133B3;EGYPTIAN HIEROGLYPH W004;Lo;0;L;;;;;N;;;;; +133B4;EGYPTIAN HIEROGLYPH W005;Lo;0;L;;;;;N;;;;; +133B5;EGYPTIAN HIEROGLYPH W006;Lo;0;L;;;;;N;;;;; +133B6;EGYPTIAN HIEROGLYPH W007;Lo;0;L;;;;;N;;;;; +133B7;EGYPTIAN HIEROGLYPH W008;Lo;0;L;;;;;N;;;;; +133B8;EGYPTIAN HIEROGLYPH W009;Lo;0;L;;;;;N;;;;; +133B9;EGYPTIAN HIEROGLYPH W009A;Lo;0;L;;;;;N;;;;; +133BA;EGYPTIAN HIEROGLYPH W010;Lo;0;L;;;;;N;;;;; +133BB;EGYPTIAN HIEROGLYPH W010A;Lo;0;L;;;;;N;;;;; +133BC;EGYPTIAN HIEROGLYPH W011;Lo;0;L;;;;;N;;;;; +133BD;EGYPTIAN HIEROGLYPH W012;Lo;0;L;;;;;N;;;;; +133BE;EGYPTIAN HIEROGLYPH W013;Lo;0;L;;;;;N;;;;; +133BF;EGYPTIAN HIEROGLYPH W014;Lo;0;L;;;;;N;;;;; +133C0;EGYPTIAN HIEROGLYPH W014A;Lo;0;L;;;;;N;;;;; +133C1;EGYPTIAN HIEROGLYPH W015;Lo;0;L;;;;;N;;;;; +133C2;EGYPTIAN HIEROGLYPH W016;Lo;0;L;;;;;N;;;;; +133C3;EGYPTIAN HIEROGLYPH W017;Lo;0;L;;;;;N;;;;; +133C4;EGYPTIAN HIEROGLYPH W017A;Lo;0;L;;;;;N;;;;; +133C5;EGYPTIAN HIEROGLYPH W018;Lo;0;L;;;;;N;;;;; +133C6;EGYPTIAN HIEROGLYPH W018A;Lo;0;L;;;;;N;;;;; +133C7;EGYPTIAN HIEROGLYPH W019;Lo;0;L;;;;;N;;;;; +133C8;EGYPTIAN HIEROGLYPH W020;Lo;0;L;;;;;N;;;;; +133C9;EGYPTIAN HIEROGLYPH W021;Lo;0;L;;;;;N;;;;; +133CA;EGYPTIAN HIEROGLYPH W022;Lo;0;L;;;;;N;;;;; +133CB;EGYPTIAN HIEROGLYPH W023;Lo;0;L;;;;;N;;;;; +133CC;EGYPTIAN HIEROGLYPH W024;Lo;0;L;;;;;N;;;;; +133CD;EGYPTIAN HIEROGLYPH W024A;Lo;0;L;;;;;N;;;;; +133CE;EGYPTIAN HIEROGLYPH W025;Lo;0;L;;;;;N;;;;; +133CF;EGYPTIAN HIEROGLYPH X001;Lo;0;L;;;;;N;;;;; +133D0;EGYPTIAN HIEROGLYPH X002;Lo;0;L;;;;;N;;;;; +133D1;EGYPTIAN HIEROGLYPH X003;Lo;0;L;;;;;N;;;;; +133D2;EGYPTIAN HIEROGLYPH X004;Lo;0;L;;;;;N;;;;; +133D3;EGYPTIAN HIEROGLYPH X004A;Lo;0;L;;;;;N;;;;; +133D4;EGYPTIAN HIEROGLYPH X004B;Lo;0;L;;;;;N;;;;; +133D5;EGYPTIAN HIEROGLYPH X005;Lo;0;L;;;;;N;;;;; +133D6;EGYPTIAN HIEROGLYPH X006;Lo;0;L;;;;;N;;;;; +133D7;EGYPTIAN HIEROGLYPH X006A;Lo;0;L;;;;;N;;;;; +133D8;EGYPTIAN HIEROGLYPH X007;Lo;0;L;;;;;N;;;;; +133D9;EGYPTIAN HIEROGLYPH X008;Lo;0;L;;;;;N;;;;; +133DA;EGYPTIAN HIEROGLYPH X008A;Lo;0;L;;;;;N;;;;; +133DB;EGYPTIAN HIEROGLYPH Y001;Lo;0;L;;;;;N;;;;; +133DC;EGYPTIAN HIEROGLYPH Y001A;Lo;0;L;;;;;N;;;;; +133DD;EGYPTIAN HIEROGLYPH Y002;Lo;0;L;;;;;N;;;;; +133DE;EGYPTIAN HIEROGLYPH Y003;Lo;0;L;;;;;N;;;;; +133DF;EGYPTIAN HIEROGLYPH Y004;Lo;0;L;;;;;N;;;;; +133E0;EGYPTIAN HIEROGLYPH Y005;Lo;0;L;;;;;N;;;;; +133E1;EGYPTIAN HIEROGLYPH Y006;Lo;0;L;;;;;N;;;;; +133E2;EGYPTIAN HIEROGLYPH Y007;Lo;0;L;;;;;N;;;;; +133E3;EGYPTIAN HIEROGLYPH Y008;Lo;0;L;;;;;N;;;;; +133E4;EGYPTIAN HIEROGLYPH Z001;Lo;0;L;;;;;N;;;;; +133E5;EGYPTIAN HIEROGLYPH Z002;Lo;0;L;;;;;N;;;;; +133E6;EGYPTIAN HIEROGLYPH Z002A;Lo;0;L;;;;;N;;;;; +133E7;EGYPTIAN HIEROGLYPH Z002B;Lo;0;L;;;;;N;;;;; +133E8;EGYPTIAN HIEROGLYPH Z002C;Lo;0;L;;;;;N;;;;; +133E9;EGYPTIAN HIEROGLYPH Z002D;Lo;0;L;;;;;N;;;;; +133EA;EGYPTIAN HIEROGLYPH Z003;Lo;0;L;;;;;N;;;;; +133EB;EGYPTIAN HIEROGLYPH Z003A;Lo;0;L;;;;;N;;;;; +133EC;EGYPTIAN HIEROGLYPH Z003B;Lo;0;L;;;;;N;;;;; +133ED;EGYPTIAN HIEROGLYPH Z004;Lo;0;L;;;;;N;;;;; +133EE;EGYPTIAN HIEROGLYPH Z004A;Lo;0;L;;;;;N;;;;; +133EF;EGYPTIAN HIEROGLYPH Z005;Lo;0;L;;;;;N;;;;; +133F0;EGYPTIAN HIEROGLYPH Z005A;Lo;0;L;;;;;N;;;;; +133F1;EGYPTIAN HIEROGLYPH Z006;Lo;0;L;;;;;N;;;;; +133F2;EGYPTIAN HIEROGLYPH Z007;Lo;0;L;;;;;N;;;;; +133F3;EGYPTIAN HIEROGLYPH Z008;Lo;0;L;;;;;N;;;;; +133F4;EGYPTIAN HIEROGLYPH Z009;Lo;0;L;;;;;N;;;;; +133F5;EGYPTIAN HIEROGLYPH Z010;Lo;0;L;;;;;N;;;;; +133F6;EGYPTIAN HIEROGLYPH Z011;Lo;0;L;;;;;N;;;;; +133F7;EGYPTIAN HIEROGLYPH Z012;Lo;0;L;;;;;N;;;;; +133F8;EGYPTIAN HIEROGLYPH Z013;Lo;0;L;;;;;N;;;;; +133F9;EGYPTIAN HIEROGLYPH Z014;Lo;0;L;;;;;N;;;;; +133FA;EGYPTIAN HIEROGLYPH Z015;Lo;0;L;;;;;N;;;;; +133FB;EGYPTIAN HIEROGLYPH Z015A;Lo;0;L;;;;;N;;;;; +133FC;EGYPTIAN HIEROGLYPH Z015B;Lo;0;L;;;;;N;;;;; +133FD;EGYPTIAN HIEROGLYPH Z015C;Lo;0;L;;;;;N;;;;; +133FE;EGYPTIAN HIEROGLYPH Z015D;Lo;0;L;;;;;N;;;;; +133FF;EGYPTIAN HIEROGLYPH Z015E;Lo;0;L;;;;;N;;;;; +13400;EGYPTIAN HIEROGLYPH Z015F;Lo;0;L;;;;;N;;;;; +13401;EGYPTIAN HIEROGLYPH Z015G;Lo;0;L;;;;;N;;;;; +13402;EGYPTIAN HIEROGLYPH Z015H;Lo;0;L;;;;;N;;;;; +13403;EGYPTIAN HIEROGLYPH Z015I;Lo;0;L;;;;;N;;;;; +13404;EGYPTIAN HIEROGLYPH Z016;Lo;0;L;;;;;N;;;;; +13405;EGYPTIAN HIEROGLYPH Z016A;Lo;0;L;;;;;N;;;;; +13406;EGYPTIAN HIEROGLYPH Z016B;Lo;0;L;;;;;N;;;;; +13407;EGYPTIAN HIEROGLYPH Z016C;Lo;0;L;;;;;N;;;;; +13408;EGYPTIAN HIEROGLYPH Z016D;Lo;0;L;;;;;N;;;;; +13409;EGYPTIAN HIEROGLYPH Z016E;Lo;0;L;;;;;N;;;;; +1340A;EGYPTIAN HIEROGLYPH Z016F;Lo;0;L;;;;;N;;;;; +1340B;EGYPTIAN HIEROGLYPH Z016G;Lo;0;L;;;;;N;;;;; +1340C;EGYPTIAN HIEROGLYPH Z016H;Lo;0;L;;;;;N;;;;; +1340D;EGYPTIAN HIEROGLYPH AA001;Lo;0;L;;;;;N;;;;; +1340E;EGYPTIAN HIEROGLYPH AA002;Lo;0;L;;;;;N;;;;; +1340F;EGYPTIAN HIEROGLYPH AA003;Lo;0;L;;;;;N;;;;; +13410;EGYPTIAN HIEROGLYPH AA004;Lo;0;L;;;;;N;;;;; +13411;EGYPTIAN HIEROGLYPH AA005;Lo;0;L;;;;;N;;;;; +13412;EGYPTIAN HIEROGLYPH AA006;Lo;0;L;;;;;N;;;;; +13413;EGYPTIAN HIEROGLYPH AA007;Lo;0;L;;;;;N;;;;; +13414;EGYPTIAN HIEROGLYPH AA007A;Lo;0;L;;;;;N;;;;; +13415;EGYPTIAN HIEROGLYPH AA007B;Lo;0;L;;;;;N;;;;; +13416;EGYPTIAN HIEROGLYPH AA008;Lo;0;L;;;;;N;;;;; +13417;EGYPTIAN HIEROGLYPH AA009;Lo;0;L;;;;;N;;;;; +13418;EGYPTIAN HIEROGLYPH AA010;Lo;0;L;;;;;N;;;;; +13419;EGYPTIAN HIEROGLYPH AA011;Lo;0;L;;;;;N;;;;; +1341A;EGYPTIAN HIEROGLYPH AA012;Lo;0;L;;;;;N;;;;; +1341B;EGYPTIAN HIEROGLYPH AA013;Lo;0;L;;;;;N;;;;; +1341C;EGYPTIAN HIEROGLYPH AA014;Lo;0;L;;;;;N;;;;; +1341D;EGYPTIAN HIEROGLYPH AA015;Lo;0;L;;;;;N;;;;; +1341E;EGYPTIAN HIEROGLYPH AA016;Lo;0;L;;;;;N;;;;; +1341F;EGYPTIAN HIEROGLYPH AA017;Lo;0;L;;;;;N;;;;; +13420;EGYPTIAN HIEROGLYPH AA018;Lo;0;L;;;;;N;;;;; +13421;EGYPTIAN HIEROGLYPH AA019;Lo;0;L;;;;;N;;;;; +13422;EGYPTIAN HIEROGLYPH AA020;Lo;0;L;;;;;N;;;;; +13423;EGYPTIAN HIEROGLYPH AA021;Lo;0;L;;;;;N;;;;; +13424;EGYPTIAN HIEROGLYPH AA022;Lo;0;L;;;;;N;;;;; +13425;EGYPTIAN HIEROGLYPH AA023;Lo;0;L;;;;;N;;;;; +13426;EGYPTIAN HIEROGLYPH AA024;Lo;0;L;;;;;N;;;;; +13427;EGYPTIAN HIEROGLYPH AA025;Lo;0;L;;;;;N;;;;; +13428;EGYPTIAN HIEROGLYPH AA026;Lo;0;L;;;;;N;;;;; +13429;EGYPTIAN HIEROGLYPH AA027;Lo;0;L;;;;;N;;;;; +1342A;EGYPTIAN HIEROGLYPH AA028;Lo;0;L;;;;;N;;;;; +1342B;EGYPTIAN HIEROGLYPH AA029;Lo;0;L;;;;;N;;;;; +1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;; +1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;; +1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;; 1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;; 1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;; 1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;; @@ -17204,12 +19588,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;; 1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;; 1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;; -1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;ren *;;; -1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;tian ren *;;; -1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;di ren *;;; -1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;ren tian *;;; -1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;ren di *;;; -1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;ren ren *;;; +1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;;;; +1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;;;; +1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;;;; +1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;;;; +1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; 1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;; 1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;; 1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;; @@ -18014,7 +20398,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; -1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; 1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; @@ -18072,7 +20456,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; -1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; 1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; @@ -18130,7 +20514,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; -1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; 1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; @@ -18188,7 +20572,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; -1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; 1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; @@ -18246,7 +20630,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; -1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;Y;;;;; +1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; 1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; @@ -18449,8 +20833,117 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;; 1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;; 1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;; +1F100;DIGIT ZERO FULL STOP;No;0;EN; 0030 002E;;0;0;N;;;;; +1F101;DIGIT ZERO COMMA;No;0;EN; 0030 002C;;0;0;N;;;;; +1F102;DIGIT ONE COMMA;No;0;EN; 0031 002C;;1;1;N;;;;; +1F103;DIGIT TWO COMMA;No;0;EN; 0032 002C;;2;2;N;;;;; +1F104;DIGIT THREE COMMA;No;0;EN; 0033 002C;;3;3;N;;;;; +1F105;DIGIT FOUR COMMA;No;0;EN; 0034 002C;;4;4;N;;;;; +1F106;DIGIT FIVE COMMA;No;0;EN; 0035 002C;;5;5;N;;;;; +1F107;DIGIT SIX COMMA;No;0;EN; 0036 002C;;6;6;N;;;;; +1F108;DIGIT SEVEN COMMA;No;0;EN; 0037 002C;;7;7;N;;;;; +1F109;DIGIT EIGHT COMMA;No;0;EN; 0038 002C;;8;8;N;;;;; +1F10A;DIGIT NINE COMMA;No;0;EN; 0039 002C;;9;9;N;;;;; +1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L; 0028 0041 0029;;;;N;;;;; +1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L; 0028 0042 0029;;;;N;;;;; +1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L; 0028 0043 0029;;;;N;;;;; +1F113;PARENTHESIZED LATIN CAPITAL LETTER D;So;0;L; 0028 0044 0029;;;;N;;;;; +1F114;PARENTHESIZED LATIN CAPITAL LETTER E;So;0;L; 0028 0045 0029;;;;N;;;;; +1F115;PARENTHESIZED LATIN CAPITAL LETTER F;So;0;L; 0028 0046 0029;;;;N;;;;; +1F116;PARENTHESIZED LATIN CAPITAL LETTER G;So;0;L; 0028 0047 0029;;;;N;;;;; +1F117;PARENTHESIZED LATIN CAPITAL LETTER H;So;0;L; 0028 0048 0029;;;;N;;;;; +1F118;PARENTHESIZED LATIN CAPITAL LETTER I;So;0;L; 0028 0049 0029;;;;N;;;;; +1F119;PARENTHESIZED LATIN CAPITAL LETTER J;So;0;L; 0028 004A 0029;;;;N;;;;; +1F11A;PARENTHESIZED LATIN CAPITAL LETTER K;So;0;L; 0028 004B 0029;;;;N;;;;; +1F11B;PARENTHESIZED LATIN CAPITAL LETTER L;So;0;L; 0028 004C 0029;;;;N;;;;; +1F11C;PARENTHESIZED LATIN CAPITAL LETTER M;So;0;L; 0028 004D 0029;;;;N;;;;; +1F11D;PARENTHESIZED LATIN CAPITAL LETTER N;So;0;L; 0028 004E 0029;;;;N;;;;; +1F11E;PARENTHESIZED LATIN CAPITAL LETTER O;So;0;L; 0028 004F 0029;;;;N;;;;; +1F11F;PARENTHESIZED LATIN CAPITAL LETTER P;So;0;L; 0028 0050 0029;;;;N;;;;; +1F120;PARENTHESIZED LATIN CAPITAL LETTER Q;So;0;L; 0028 0051 0029;;;;N;;;;; +1F121;PARENTHESIZED LATIN CAPITAL LETTER R;So;0;L; 0028 0052 0029;;;;N;;;;; +1F122;PARENTHESIZED LATIN CAPITAL LETTER S;So;0;L; 0028 0053 0029;;;;N;;;;; +1F123;PARENTHESIZED LATIN CAPITAL LETTER T;So;0;L; 0028 0054 0029;;;;N;;;;; +1F124;PARENTHESIZED LATIN CAPITAL LETTER U;So;0;L; 0028 0055 0029;;;;N;;;;; +1F125;PARENTHESIZED LATIN CAPITAL LETTER V;So;0;L; 0028 0056 0029;;;;N;;;;; +1F126;PARENTHESIZED LATIN CAPITAL LETTER W;So;0;L; 0028 0057 0029;;;;N;;;;; +1F127;PARENTHESIZED LATIN CAPITAL LETTER X;So;0;L; 0028 0058 0029;;;;N;;;;; +1F128;PARENTHESIZED LATIN CAPITAL LETTER Y;So;0;L; 0028 0059 0029;;;;N;;;;; +1F129;PARENTHESIZED LATIN CAPITAL LETTER Z;So;0;L; 0028 005A 0029;;;;N;;;;; +1F12A;TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S;So;0;L; 3014 0053 3015;;;;N;;;;; +1F12B;CIRCLED ITALIC LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;; +1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;; +1F12D;CIRCLED CD;So;0;L; 0043 0044;;;;N;;;;; +1F12E;CIRCLED WZ;So;0;L; 0057 005A;;;;N;;;;; +1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;; +1F13D;SQUARED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;; +1F13F;SQUARED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;; +1F142;SQUARED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;; +1F146;SQUARED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;; +1F14A;SQUARED HV;So;0;L; 0048 0056;;;;N;;;;; +1F14B;SQUARED MV;So;0;L; 004D 0056;;;;N;;;;; +1F14C;SQUARED SD;So;0;L; 0053 0044;;;;N;;;;; +1F14D;SQUARED SS;So;0;L; 0053 0053;;;;N;;;;; +1F14E;SQUARED PPV;So;0;L; 0050 0050 0056;;;;N;;;;; +1F157;NEGATIVE CIRCLED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;; +1F15F;NEGATIVE CIRCLED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F179;NEGATIVE SQUARED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;; +1F17B;NEGATIVE SQUARED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;; +1F17C;NEGATIVE SQUARED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;; +1F17F;NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F18A;CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F18B;NEGATIVE SQUARED IC;So;0;L;;;;;N;;;;; +1F18C;NEGATIVE SQUARED PA;So;0;L;;;;;N;;;;; +1F18D;NEGATIVE SQUARED SA;So;0;L;;;;;N;;;;; +1F190;SQUARE DJ;So;0;L; 0044 004A;;;;N;;;;; +1F200;SQUARE HIRAGANA HOKA;So;0;L; 307B 304B;;;;N;;;;; +1F210;SQUARED CJK UNIFIED IDEOGRAPH-624B;So;0;L; 624B;;;;N;;;;; +1F211;SQUARED CJK UNIFIED IDEOGRAPH-5B57;So;0;L; 5B57;;;;N;;;;; +1F212;SQUARED CJK UNIFIED IDEOGRAPH-53CC;So;0;L; 53CC;;;;N;;;;; +1F213;SQUARED KATAKANA DE;So;0;L; 30C7;;;;N;;;;; +1F214;SQUARED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L; 4E8C;;;;N;;;;; +1F215;SQUARED CJK UNIFIED IDEOGRAPH-591A;So;0;L; 591A;;;;N;;;;; +1F216;SQUARED CJK UNIFIED IDEOGRAPH-89E3;So;0;L; 89E3;;;;N;;;;; +1F217;SQUARED CJK UNIFIED IDEOGRAPH-5929;So;0;L; 5929;;;;N;;;;; +1F218;SQUARED CJK UNIFIED IDEOGRAPH-4EA4;So;0;L; 4EA4;;;;N;;;;; +1F219;SQUARED CJK UNIFIED IDEOGRAPH-6620;So;0;L; 6620;;;;N;;;;; +1F21A;SQUARED CJK UNIFIED IDEOGRAPH-7121;So;0;L; 7121;;;;N;;;;; +1F21B;SQUARED CJK UNIFIED IDEOGRAPH-6599;So;0;L; 6599;;;;N;;;;; +1F21C;SQUARED CJK UNIFIED IDEOGRAPH-524D;So;0;L; 524D;;;;N;;;;; +1F21D;SQUARED CJK UNIFIED IDEOGRAPH-5F8C;So;0;L; 5F8C;;;;N;;;;; +1F21E;SQUARED CJK UNIFIED IDEOGRAPH-518D;So;0;L; 518D;;;;N;;;;; +1F21F;SQUARED CJK UNIFIED IDEOGRAPH-65B0;So;0;L; 65B0;;;;N;;;;; +1F220;SQUARED CJK UNIFIED IDEOGRAPH-521D;So;0;L; 521D;;;;N;;;;; +1F221;SQUARED CJK UNIFIED IDEOGRAPH-7D42;So;0;L; 7D42;;;;N;;;;; +1F222;SQUARED CJK UNIFIED IDEOGRAPH-751F;So;0;L; 751F;;;;N;;;;; +1F223;SQUARED CJK UNIFIED IDEOGRAPH-8CA9;So;0;L; 8CA9;;;;N;;;;; +1F224;SQUARED CJK UNIFIED IDEOGRAPH-58F0;So;0;L; 58F0;;;;N;;;;; +1F225;SQUARED CJK UNIFIED IDEOGRAPH-5439;So;0;L; 5439;;;;N;;;;; +1F226;SQUARED CJK UNIFIED IDEOGRAPH-6F14;So;0;L; 6F14;;;;N;;;;; +1F227;SQUARED CJK UNIFIED IDEOGRAPH-6295;So;0;L; 6295;;;;N;;;;; +1F228;SQUARED CJK UNIFIED IDEOGRAPH-6355;So;0;L; 6355;;;;N;;;;; +1F229;SQUARED CJK UNIFIED IDEOGRAPH-4E00;So;0;L; 4E00;;;;N;;;;; +1F22A;SQUARED CJK UNIFIED IDEOGRAPH-4E09;So;0;L; 4E09;;;;N;;;;; +1F22B;SQUARED CJK UNIFIED IDEOGRAPH-904A;So;0;L; 904A;;;;N;;;;; +1F22C;SQUARED CJK UNIFIED IDEOGRAPH-5DE6;So;0;L; 5DE6;;;;N;;;;; +1F22D;SQUARED CJK UNIFIED IDEOGRAPH-4E2D;So;0;L; 4E2D;;;;N;;;;; +1F22E;SQUARED CJK UNIFIED IDEOGRAPH-53F3;So;0;L; 53F3;;;;N;;;;; +1F22F;SQUARED CJK UNIFIED IDEOGRAPH-6307;So;0;L; 6307;;;;N;;;;; +1F230;SQUARED CJK UNIFIED IDEOGRAPH-8D70;So;0;L; 8D70;;;;N;;;;; +1F231;SQUARED CJK UNIFIED IDEOGRAPH-6253;So;0;L; 6253;;;;N;;;;; +1F240;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C;So;0;L; 3014 672C 3015;;;;N;;;;; +1F241;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09;So;0;L; 3014 4E09 3015;;;;N;;;;; +1F242;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L; 3014 4E8C 3015;;;;N;;;;; +1F243;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89;So;0;L; 3014 5B89 3015;;;;N;;;;; +1F244;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9;So;0;L; 3014 70B9 3015;;;;N;;;;; +1F245;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253;So;0;L; 3014 6253 3015;;;;N;;;;; +1F246;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7;So;0;L; 3014 76D7 3015;;;;N;;;;; +1F247;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD;So;0;L; 3014 52DD 3015;;;;N;;;;; +1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L; 3014 6557 3015;;;;N;;;;; 20000;;Lo;0;L;;;;;N;;;;; 2A6D6;;Lo;0;L;;;;;N;;;;; +2A700;;Lo;0;L;;;;;N;;;;; +2B734;;Lo;0;L;;;;;N;;;;; 2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;; 2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;; 2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;; From 741b56af5ca4b8635c0c015e4e2d2a9bff0c3a11 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 23:25:14 +0100 Subject: [PATCH 087/503] Moved unicode files to separate directory --- autogen.sh | 2 +- unicode/BidiMirroring.txt | 588 ++++++++++++++++++++++++++++++ {util => unicode}/UnicodeData.txt | 0 3 files changed, 589 insertions(+), 1 deletion(-) create mode 100644 unicode/BidiMirroring.txt rename {util => unicode}/UnicodeData.txt (100%) diff --git a/autogen.sh b/autogen.sh index 524b908f5..7cbee5cca 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,7 +13,7 @@ echo timestamp > stamp-h.in python util/import_gcry.py lib/libgcrypt/ . -python util/import_unicode.py util/UnicodeData.txt util/BidiMirroring.txt unidata.c +python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unidata.c for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do if test -e $rmk ; then diff --git a/unicode/BidiMirroring.txt b/unicode/BidiMirroring.txt new file mode 100644 index 000000000..81e838a7e --- /dev/null +++ b/unicode/BidiMirroring.txt @@ -0,0 +1,588 @@ +# BidiMirroring-5.2.0.txt +# Date: 2009-05-22, 12:44:00 PDT [KW] +# +# Bidi_Mirroring_Glyph Property +# +# This file is an informative contributory data file in the +# Unicode Character Database. +# +# Copyright (c) 1991-2009 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# This data file lists characters that have the mirrored property +# where there is another Unicode character that typically has a glyph +# that is the mirror image of the original character's glyph. +# The repertoire covered by the file is Unicode 5.2.0. +# +# The file contains a list of lines with mappings from one code point +# to another one for character-based mirroring. +# Note that for "real" mirroring, a rendering engine needs to select +# appropriate alternative glyphs, and that many Unicode characters do not +# have a mirror-image Unicode character. +# +# Each mapping line contains two fields, separated by a semicolon (';'). +# Each of the two fields contains a code point represented as a +# variable-length hexadecimal value with 4 to 6 digits. +# A comment indicates where the characters are "BEST FIT" mirroring. +# +# Code points with the "mirrored" property but no appropriate mirrors are +# listed as comments at the end of the file. +# +# For information on bidi mirroring, see UAX #9: Bidirectional Algorithm, +# at http://www.unicode.org/unicode/reports/tr9/ +# +# This file was originally created by Markus Scherer. +# Extended for Unicode 3.2, 4.0, 4.1, 5.0, 5.1, and 5.2 by Ken Whistler. +# +# ############################################################ + +0028; 0029 # LEFT PARENTHESIS +0029; 0028 # RIGHT PARENTHESIS +003C; 003E # LESS-THAN SIGN +003E; 003C # GREATER-THAN SIGN +005B; 005D # LEFT SQUARE BRACKET +005D; 005B # RIGHT SQUARE BRACKET +007B; 007D # LEFT CURLY BRACKET +007D; 007B # RIGHT CURLY BRACKET +00AB; 00BB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +00BB; 00AB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0F3A; 0F3B # TIBETAN MARK GUG RTAGS GYON +0F3B; 0F3A # TIBETAN MARK GUG RTAGS GYAS +0F3C; 0F3D # TIBETAN MARK ANG KHANG GYON +0F3D; 0F3C # TIBETAN MARK ANG KHANG GYAS +169B; 169C # OGHAM FEATHER MARK +169C; 169B # OGHAM REVERSED FEATHER MARK +2039; 203A # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +203A; 2039 # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +2045; 2046 # LEFT SQUARE BRACKET WITH QUILL +2046; 2045 # RIGHT SQUARE BRACKET WITH QUILL +207D; 207E # SUPERSCRIPT LEFT PARENTHESIS +207E; 207D # SUPERSCRIPT RIGHT PARENTHESIS +208D; 208E # SUBSCRIPT LEFT PARENTHESIS +208E; 208D # SUBSCRIPT RIGHT PARENTHESIS +2208; 220B # ELEMENT OF +2209; 220C # NOT AN ELEMENT OF +220A; 220D # SMALL ELEMENT OF +220B; 2208 # CONTAINS AS MEMBER +220C; 2209 # DOES NOT CONTAIN AS MEMBER +220D; 220A # SMALL CONTAINS AS MEMBER +2215; 29F5 # DIVISION SLASH +223C; 223D # TILDE OPERATOR +223D; 223C # REVERSED TILDE +2243; 22CD # ASYMPTOTICALLY EQUAL TO +2252; 2253 # APPROXIMATELY EQUAL TO OR THE IMAGE OF +2253; 2252 # IMAGE OF OR APPROXIMATELY EQUAL TO +2254; 2255 # COLON EQUALS +2255; 2254 # EQUALS COLON +2264; 2265 # LESS-THAN OR EQUAL TO +2265; 2264 # GREATER-THAN OR EQUAL TO +2266; 2267 # LESS-THAN OVER EQUAL TO +2267; 2266 # GREATER-THAN OVER EQUAL TO +2268; 2269 # [BEST FIT] LESS-THAN BUT NOT EQUAL TO +2269; 2268 # [BEST FIT] GREATER-THAN BUT NOT EQUAL TO +226A; 226B # MUCH LESS-THAN +226B; 226A # MUCH GREATER-THAN +226E; 226F # [BEST FIT] NOT LESS-THAN +226F; 226E # [BEST FIT] NOT GREATER-THAN +2270; 2271 # [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO +2271; 2270 # [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO +2272; 2273 # [BEST FIT] LESS-THAN OR EQUIVALENT TO +2273; 2272 # [BEST FIT] GREATER-THAN OR EQUIVALENT TO +2274; 2275 # [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO +2275; 2274 # [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO +2276; 2277 # LESS-THAN OR GREATER-THAN +2277; 2276 # GREATER-THAN OR LESS-THAN +2278; 2279 # [BEST FIT] NEITHER LESS-THAN NOR GREATER-THAN +2279; 2278 # [BEST FIT] NEITHER GREATER-THAN NOR LESS-THAN +227A; 227B # PRECEDES +227B; 227A # SUCCEEDS +227C; 227D # PRECEDES OR EQUAL TO +227D; 227C # SUCCEEDS OR EQUAL TO +227E; 227F # [BEST FIT] PRECEDES OR EQUIVALENT TO +227F; 227E # [BEST FIT] SUCCEEDS OR EQUIVALENT TO +2280; 2281 # [BEST FIT] DOES NOT PRECEDE +2281; 2280 # [BEST FIT] DOES NOT SUCCEED +2282; 2283 # SUBSET OF +2283; 2282 # SUPERSET OF +2284; 2285 # [BEST FIT] NOT A SUBSET OF +2285; 2284 # [BEST FIT] NOT A SUPERSET OF +2286; 2287 # SUBSET OF OR EQUAL TO +2287; 2286 # SUPERSET OF OR EQUAL TO +2288; 2289 # [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO +2289; 2288 # [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO +228A; 228B # [BEST FIT] SUBSET OF WITH NOT EQUAL TO +228B; 228A # [BEST FIT] SUPERSET OF WITH NOT EQUAL TO +228F; 2290 # SQUARE IMAGE OF +2290; 228F # SQUARE ORIGINAL OF +2291; 2292 # SQUARE IMAGE OF OR EQUAL TO +2292; 2291 # SQUARE ORIGINAL OF OR EQUAL TO +2298; 29B8 # CIRCLED DIVISION SLASH +22A2; 22A3 # RIGHT TACK +22A3; 22A2 # LEFT TACK +22A6; 2ADE # ASSERTION +22A8; 2AE4 # TRUE +22A9; 2AE3 # FORCES +22AB; 2AE5 # DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +22B0; 22B1 # PRECEDES UNDER RELATION +22B1; 22B0 # SUCCEEDS UNDER RELATION +22B2; 22B3 # NORMAL SUBGROUP OF +22B3; 22B2 # CONTAINS AS NORMAL SUBGROUP +22B4; 22B5 # NORMAL SUBGROUP OF OR EQUAL TO +22B5; 22B4 # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +22B6; 22B7 # ORIGINAL OF +22B7; 22B6 # IMAGE OF +22C9; 22CA # LEFT NORMAL FACTOR SEMIDIRECT PRODUCT +22CA; 22C9 # RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT +22CB; 22CC # LEFT SEMIDIRECT PRODUCT +22CC; 22CB # RIGHT SEMIDIRECT PRODUCT +22CD; 2243 # REVERSED TILDE EQUALS +22D0; 22D1 # DOUBLE SUBSET +22D1; 22D0 # DOUBLE SUPERSET +22D6; 22D7 # LESS-THAN WITH DOT +22D7; 22D6 # GREATER-THAN WITH DOT +22D8; 22D9 # VERY MUCH LESS-THAN +22D9; 22D8 # VERY MUCH GREATER-THAN +22DA; 22DB # LESS-THAN EQUAL TO OR GREATER-THAN +22DB; 22DA # GREATER-THAN EQUAL TO OR LESS-THAN +22DC; 22DD # EQUAL TO OR LESS-THAN +22DD; 22DC # EQUAL TO OR GREATER-THAN +22DE; 22DF # EQUAL TO OR PRECEDES +22DF; 22DE # EQUAL TO OR SUCCEEDS +22E0; 22E1 # [BEST FIT] DOES NOT PRECEDE OR EQUAL +22E1; 22E0 # [BEST FIT] DOES NOT SUCCEED OR EQUAL +22E2; 22E3 # [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO +22E3; 22E2 # [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO +22E4; 22E5 # [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO +22E5; 22E4 # [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO +22E6; 22E7 # [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO +22E7; 22E6 # [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO +22E8; 22E9 # [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO +22E9; 22E8 # [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO +22EA; 22EB # [BEST FIT] NOT NORMAL SUBGROUP OF +22EB; 22EA # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP +22EC; 22ED # [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO +22ED; 22EC # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +22F0; 22F1 # UP RIGHT DIAGONAL ELLIPSIS +22F1; 22F0 # DOWN RIGHT DIAGONAL ELLIPSIS +22F2; 22FA # ELEMENT OF WITH LONG HORIZONTAL STROKE +22F3; 22FB # ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22F4; 22FC # SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22F6; 22FD # ELEMENT OF WITH OVERBAR +22F7; 22FE # SMALL ELEMENT OF WITH OVERBAR +22FA; 22F2 # CONTAINS WITH LONG HORIZONTAL STROKE +22FB; 22F3 # CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22FC; 22F4 # SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22FD; 22F6 # CONTAINS WITH OVERBAR +22FE; 22F7 # SMALL CONTAINS WITH OVERBAR +2308; 2309 # LEFT CEILING +2309; 2308 # RIGHT CEILING +230A; 230B # LEFT FLOOR +230B; 230A # RIGHT FLOOR +2329; 232A # LEFT-POINTING ANGLE BRACKET +232A; 2329 # RIGHT-POINTING ANGLE BRACKET +2768; 2769 # MEDIUM LEFT PARENTHESIS ORNAMENT +2769; 2768 # MEDIUM RIGHT PARENTHESIS ORNAMENT +276A; 276B # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT +276B; 276A # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT +276C; 276D # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT +276D; 276C # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT +276E; 276F # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT +276F; 276E # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT +2770; 2771 # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT +2771; 2770 # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT +2772; 2773 # LIGHT LEFT TORTOISE SHELL BRACKET +2773; 2772 # LIGHT RIGHT TORTOISE SHELL BRACKET +2774; 2775 # MEDIUM LEFT CURLY BRACKET ORNAMENT +2775; 2774 # MEDIUM RIGHT CURLY BRACKET ORNAMENT +27C3; 27C4 # OPEN SUBSET +27C4; 27C3 # OPEN SUPERSET +27C5; 27C6 # LEFT S-SHAPED BAG DELIMITER +27C6; 27C5 # RIGHT S-SHAPED BAG DELIMITER +27C8; 27C9 # REVERSE SOLIDUS PRECEDING SUBSET +27C9; 27C8 # SUPERSET PRECEDING SOLIDUS +27D5; 27D6 # LEFT OUTER JOIN +27D6; 27D5 # RIGHT OUTER JOIN +27DD; 27DE # LONG RIGHT TACK +27DE; 27DD # LONG LEFT TACK +27E2; 27E3 # WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK +27E3; 27E2 # WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK +27E4; 27E5 # WHITE SQUARE WITH LEFTWARDS TICK +27E5; 27E4 # WHITE SQUARE WITH RIGHTWARDS TICK +27E6; 27E7 # MATHEMATICAL LEFT WHITE SQUARE BRACKET +27E7; 27E6 # MATHEMATICAL RIGHT WHITE SQUARE BRACKET +27E8; 27E9 # MATHEMATICAL LEFT ANGLE BRACKET +27E9; 27E8 # MATHEMATICAL RIGHT ANGLE BRACKET +27EA; 27EB # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +27EB; 27EA # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +27EC; 27ED # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +27ED; 27EC # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +27EE; 27EF # MATHEMATICAL LEFT FLATTENED PARENTHESIS +27EF; 27EE # MATHEMATICAL RIGHT FLATTENED PARENTHESIS +2983; 2984 # LEFT WHITE CURLY BRACKET +2984; 2983 # RIGHT WHITE CURLY BRACKET +2985; 2986 # LEFT WHITE PARENTHESIS +2986; 2985 # RIGHT WHITE PARENTHESIS +2987; 2988 # Z NOTATION LEFT IMAGE BRACKET +2988; 2987 # Z NOTATION RIGHT IMAGE BRACKET +2989; 298A # Z NOTATION LEFT BINDING BRACKET +298A; 2989 # Z NOTATION RIGHT BINDING BRACKET +298B; 298C # LEFT SQUARE BRACKET WITH UNDERBAR +298C; 298B # RIGHT SQUARE BRACKET WITH UNDERBAR +298D; 2990 # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +298E; 298F # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +298F; 298E # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2990; 298D # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +2991; 2992 # LEFT ANGLE BRACKET WITH DOT +2992; 2991 # RIGHT ANGLE BRACKET WITH DOT +2993; 2994 # LEFT ARC LESS-THAN BRACKET +2994; 2993 # RIGHT ARC GREATER-THAN BRACKET +2995; 2996 # DOUBLE LEFT ARC GREATER-THAN BRACKET +2996; 2995 # DOUBLE RIGHT ARC LESS-THAN BRACKET +2997; 2998 # LEFT BLACK TORTOISE SHELL BRACKET +2998; 2997 # RIGHT BLACK TORTOISE SHELL BRACKET +29B8; 2298 # CIRCLED REVERSE SOLIDUS +29C0; 29C1 # CIRCLED LESS-THAN +29C1; 29C0 # CIRCLED GREATER-THAN +29C4; 29C5 # SQUARED RISING DIAGONAL SLASH +29C5; 29C4 # SQUARED FALLING DIAGONAL SLASH +29CF; 29D0 # LEFT TRIANGLE BESIDE VERTICAL BAR +29D0; 29CF # VERTICAL BAR BESIDE RIGHT TRIANGLE +29D1; 29D2 # BOWTIE WITH LEFT HALF BLACK +29D2; 29D1 # BOWTIE WITH RIGHT HALF BLACK +29D4; 29D5 # TIMES WITH LEFT HALF BLACK +29D5; 29D4 # TIMES WITH RIGHT HALF BLACK +29D8; 29D9 # LEFT WIGGLY FENCE +29D9; 29D8 # RIGHT WIGGLY FENCE +29DA; 29DB # LEFT DOUBLE WIGGLY FENCE +29DB; 29DA # RIGHT DOUBLE WIGGLY FENCE +29F5; 2215 # REVERSE SOLIDUS OPERATOR +29F8; 29F9 # BIG SOLIDUS +29F9; 29F8 # BIG REVERSE SOLIDUS +29FC; 29FD # LEFT-POINTING CURVED ANGLE BRACKET +29FD; 29FC # RIGHT-POINTING CURVED ANGLE BRACKET +2A2B; 2A2C # MINUS SIGN WITH FALLING DOTS +2A2C; 2A2B # MINUS SIGN WITH RISING DOTS +2A2D; 2A2E # PLUS SIGN IN LEFT HALF CIRCLE +2A2E; 2A2D # PLUS SIGN IN RIGHT HALF CIRCLE +2A34; 2A35 # MULTIPLICATION SIGN IN LEFT HALF CIRCLE +2A35; 2A34 # MULTIPLICATION SIGN IN RIGHT HALF CIRCLE +2A3C; 2A3D # INTERIOR PRODUCT +2A3D; 2A3C # RIGHTHAND INTERIOR PRODUCT +2A64; 2A65 # Z NOTATION DOMAIN ANTIRESTRICTION +2A65; 2A64 # Z NOTATION RANGE ANTIRESTRICTION +2A79; 2A7A # LESS-THAN WITH CIRCLE INSIDE +2A7A; 2A79 # GREATER-THAN WITH CIRCLE INSIDE +2A7D; 2A7E # LESS-THAN OR SLANTED EQUAL TO +2A7E; 2A7D # GREATER-THAN OR SLANTED EQUAL TO +2A7F; 2A80 # LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +2A80; 2A7F # GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +2A81; 2A82 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +2A82; 2A81 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +2A83; 2A84 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT +2A84; 2A83 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT +2A8B; 2A8C # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN +2A8C; 2A8B # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN +2A91; 2A92 # LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL +2A92; 2A91 # GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL +2A93; 2A94 # LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL +2A94; 2A93 # GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL +2A95; 2A96 # SLANTED EQUAL TO OR LESS-THAN +2A96; 2A95 # SLANTED EQUAL TO OR GREATER-THAN +2A97; 2A98 # SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE +2A98; 2A97 # SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE +2A99; 2A9A # DOUBLE-LINE EQUAL TO OR LESS-THAN +2A9A; 2A99 # DOUBLE-LINE EQUAL TO OR GREATER-THAN +2A9B; 2A9C # DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN +2A9C; 2A9B # DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN +2AA1; 2AA2 # DOUBLE NESTED LESS-THAN +2AA2; 2AA1 # DOUBLE NESTED GREATER-THAN +2AA6; 2AA7 # LESS-THAN CLOSED BY CURVE +2AA7; 2AA6 # GREATER-THAN CLOSED BY CURVE +2AA8; 2AA9 # LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +2AA9; 2AA8 # GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +2AAA; 2AAB # SMALLER THAN +2AAB; 2AAA # LARGER THAN +2AAC; 2AAD # SMALLER THAN OR EQUAL TO +2AAD; 2AAC # LARGER THAN OR EQUAL TO +2AAF; 2AB0 # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +2AB0; 2AAF # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +2AB3; 2AB4 # PRECEDES ABOVE EQUALS SIGN +2AB4; 2AB3 # SUCCEEDS ABOVE EQUALS SIGN +2ABB; 2ABC # DOUBLE PRECEDES +2ABC; 2ABB # DOUBLE SUCCEEDS +2ABD; 2ABE # SUBSET WITH DOT +2ABE; 2ABD # SUPERSET WITH DOT +2ABF; 2AC0 # SUBSET WITH PLUS SIGN BELOW +2AC0; 2ABF # SUPERSET WITH PLUS SIGN BELOW +2AC1; 2AC2 # SUBSET WITH MULTIPLICATION SIGN BELOW +2AC2; 2AC1 # SUPERSET WITH MULTIPLICATION SIGN BELOW +2AC3; 2AC4 # SUBSET OF OR EQUAL TO WITH DOT ABOVE +2AC4; 2AC3 # SUPERSET OF OR EQUAL TO WITH DOT ABOVE +2AC5; 2AC6 # SUBSET OF ABOVE EQUALS SIGN +2AC6; 2AC5 # SUPERSET OF ABOVE EQUALS SIGN +2ACD; 2ACE # SQUARE LEFT OPEN BOX OPERATOR +2ACE; 2ACD # SQUARE RIGHT OPEN BOX OPERATOR +2ACF; 2AD0 # CLOSED SUBSET +2AD0; 2ACF # CLOSED SUPERSET +2AD1; 2AD2 # CLOSED SUBSET OR EQUAL TO +2AD2; 2AD1 # CLOSED SUPERSET OR EQUAL TO +2AD3; 2AD4 # SUBSET ABOVE SUPERSET +2AD4; 2AD3 # SUPERSET ABOVE SUBSET +2AD5; 2AD6 # SUBSET ABOVE SUBSET +2AD6; 2AD5 # SUPERSET ABOVE SUPERSET +2ADE; 22A6 # SHORT LEFT TACK +2AE3; 22A9 # DOUBLE VERTICAL BAR LEFT TURNSTILE +2AE4; 22A8 # VERTICAL BAR DOUBLE LEFT TURNSTILE +2AE5; 22AB # DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE +2AEC; 2AED # DOUBLE STROKE NOT SIGN +2AED; 2AEC # REVERSED DOUBLE STROKE NOT SIGN +2AF7; 2AF8 # TRIPLE NESTED LESS-THAN +2AF8; 2AF7 # TRIPLE NESTED GREATER-THAN +2AF9; 2AFA # DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO +2AFA; 2AF9 # DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO +2E02; 2E03 # LEFT SUBSTITUTION BRACKET +2E03; 2E02 # RIGHT SUBSTITUTION BRACKET +2E04; 2E05 # LEFT DOTTED SUBSTITUTION BRACKET +2E05; 2E04 # RIGHT DOTTED SUBSTITUTION BRACKET +2E09; 2E0A # LEFT TRANSPOSITION BRACKET +2E0A; 2E09 # RIGHT TRANSPOSITION BRACKET +2E0C; 2E0D # LEFT RAISED OMISSION BRACKET +2E0D; 2E0C # RIGHT RAISED OMISSION BRACKET +2E1C; 2E1D # LEFT LOW PARAPHRASE BRACKET +2E1D; 2E1C # RIGHT LOW PARAPHRASE BRACKET +2E20; 2E21 # LEFT VERTICAL BAR WITH QUILL +2E21; 2E20 # RIGHT VERTICAL BAR WITH QUILL +2E22; 2E23 # TOP LEFT HALF BRACKET +2E23; 2E22 # TOP RIGHT HALF BRACKET +2E24; 2E25 # BOTTOM LEFT HALF BRACKET +2E25; 2E24 # BOTTOM RIGHT HALF BRACKET +2E26; 2E27 # LEFT SIDEWAYS U BRACKET +2E27; 2E26 # RIGHT SIDEWAYS U BRACKET +2E28; 2E29 # LEFT DOUBLE PARENTHESIS +2E29; 2E28 # RIGHT DOUBLE PARENTHESIS +3008; 3009 # LEFT ANGLE BRACKET +3009; 3008 # RIGHT ANGLE BRACKET +300A; 300B # LEFT DOUBLE ANGLE BRACKET +300B; 300A # RIGHT DOUBLE ANGLE BRACKET +300C; 300D # [BEST FIT] LEFT CORNER BRACKET +300D; 300C # [BEST FIT] RIGHT CORNER BRACKET +300E; 300F # [BEST FIT] LEFT WHITE CORNER BRACKET +300F; 300E # [BEST FIT] RIGHT WHITE CORNER BRACKET +3010; 3011 # LEFT BLACK LENTICULAR BRACKET +3011; 3010 # RIGHT BLACK LENTICULAR BRACKET +3014; 3015 # LEFT TORTOISE SHELL BRACKET +3015; 3014 # RIGHT TORTOISE SHELL BRACKET +3016; 3017 # LEFT WHITE LENTICULAR BRACKET +3017; 3016 # RIGHT WHITE LENTICULAR BRACKET +3018; 3019 # LEFT WHITE TORTOISE SHELL BRACKET +3019; 3018 # RIGHT WHITE TORTOISE SHELL BRACKET +301A; 301B # LEFT WHITE SQUARE BRACKET +301B; 301A # RIGHT WHITE SQUARE BRACKET +FE59; FE5A # SMALL LEFT PARENTHESIS +FE5A; FE59 # SMALL RIGHT PARENTHESIS +FE5B; FE5C # SMALL LEFT CURLY BRACKET +FE5C; FE5B # SMALL RIGHT CURLY BRACKET +FE5D; FE5E # SMALL LEFT TORTOISE SHELL BRACKET +FE5E; FE5D # SMALL RIGHT TORTOISE SHELL BRACKET +FE64; FE65 # SMALL LESS-THAN SIGN +FE65; FE64 # SMALL GREATER-THAN SIGN +FF08; FF09 # FULLWIDTH LEFT PARENTHESIS +FF09; FF08 # FULLWIDTH RIGHT PARENTHESIS +FF1C; FF1E # FULLWIDTH LESS-THAN SIGN +FF1E; FF1C # FULLWIDTH GREATER-THAN SIGN +FF3B; FF3D # FULLWIDTH LEFT SQUARE BRACKET +FF3D; FF3B # FULLWIDTH RIGHT SQUARE BRACKET +FF5B; FF5D # FULLWIDTH LEFT CURLY BRACKET +FF5D; FF5B # FULLWIDTH RIGHT CURLY BRACKET +FF5F; FF60 # FULLWIDTH LEFT WHITE PARENTHESIS +FF60; FF5F # FULLWIDTH RIGHT WHITE PARENTHESIS +FF62; FF63 # [BEST FIT] HALFWIDTH LEFT CORNER BRACKET +FF63; FF62 # [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET + +# The following characters have no appropriate mirroring character. +# For these characters it is up to the rendering system +# to provide mirrored glyphs. + +# 2140; DOUBLE-STRUCK N-ARY SUMMATION +# 2201; COMPLEMENT +# 2202; PARTIAL DIFFERENTIAL +# 2203; THERE EXISTS +# 2204; THERE DOES NOT EXIST +# 2211; N-ARY SUMMATION +# 2216; SET MINUS +# 221A; SQUARE ROOT +# 221B; CUBE ROOT +# 221C; FOURTH ROOT +# 221D; PROPORTIONAL TO +# 221F; RIGHT ANGLE +# 2220; ANGLE +# 2221; MEASURED ANGLE +# 2222; SPHERICAL ANGLE +# 2224; DOES NOT DIVIDE +# 2226; NOT PARALLEL TO +# 222B; INTEGRAL +# 222C; DOUBLE INTEGRAL +# 222D; TRIPLE INTEGRAL +# 222E; CONTOUR INTEGRAL +# 222F; SURFACE INTEGRAL +# 2230; VOLUME INTEGRAL +# 2231; CLOCKWISE INTEGRAL +# 2232; CLOCKWISE CONTOUR INTEGRAL +# 2233; ANTICLOCKWISE CONTOUR INTEGRAL +# 2239; EXCESS +# 223B; HOMOTHETIC +# 223E; INVERTED LAZY S +# 223F; SINE WAVE +# 2240; WREATH PRODUCT +# 2241; NOT TILDE +# 2242; MINUS TILDE +# 2244; NOT ASYMPTOTICALLY EQUAL TO +# 2245; APPROXIMATELY EQUAL TO +# 2246; APPROXIMATELY BUT NOT ACTUALLY EQUAL TO +# 2247; NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +# 2248; ALMOST EQUAL TO +# 2249; NOT ALMOST EQUAL TO +# 224A; ALMOST EQUAL OR EQUAL TO +# 224B; TRIPLE TILDE +# 224C; ALL EQUAL TO +# 225F; QUESTIONED EQUAL TO +# 2260; NOT EQUAL TO +# 2262; NOT IDENTICAL TO +# 228C; MULTISET +# 22A7; MODELS +# 22AA; TRIPLE VERTICAL BAR RIGHT TURNSTILE +# 22AC; DOES NOT PROVE +# 22AD; NOT TRUE +# 22AE; DOES NOT FORCE +# 22AF; NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +# 22B8; MULTIMAP +# 22BE; RIGHT ANGLE WITH ARC +# 22BF; RIGHT TRIANGLE +# 22F5; ELEMENT OF WITH DOT ABOVE +# 22F8; ELEMENT OF WITH UNDERBAR +# 22F9; ELEMENT OF WITH TWO HORIZONTAL STROKES +# 22FF; Z NOTATION BAG MEMBERSHIP +# 2320; TOP HALF INTEGRAL +# 2321; BOTTOM HALF INTEGRAL +# 27CC; LONG DIVISION +# 27C0; THREE DIMENSIONAL ANGLE +# 27D3; LOWER RIGHT CORNER WITH DOT +# 27D4; UPPER LEFT CORNER WITH DOT +# 27DC; LEFT MULTIMAP +# 299B; MEASURED ANGLE OPENING LEFT +# 299C; RIGHT ANGLE VARIANT WITH SQUARE +# 299D; MEASURED RIGHT ANGLE WITH DOT +# 299E; ANGLE WITH S INSIDE +# 299F; ACUTE ANGLE +# 29A0; SPHERICAL ANGLE OPENING LEFT +# 29A1; SPHERICAL ANGLE OPENING UP +# 29A2; TURNED ANGLE +# 29A3; REVERSED ANGLE +# 29A4; ANGLE WITH UNDERBAR +# 29A5; REVERSED ANGLE WITH UNDERBAR +# 29A6; OBLIQUE ANGLE OPENING UP +# 29A7; OBLIQUE ANGLE OPENING DOWN +# 29A8; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT +# 29A9; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT +# 29AA; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT +# 29AB; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT +# 29AC; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP +# 29AD; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP +# 29AE; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN +# 29AF; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN +# 29C2; CIRCLE WITH SMALL CIRCLE TO THE RIGHT +# 29C3; CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT +# 29C9; TWO JOINED SQUARES +# 29CE; RIGHT TRIANGLE ABOVE LEFT TRIANGLE +# 29DC; INCOMPLETE INFINITY +# 29E1; INCREASES AS +# 29E3; EQUALS SIGN AND SLANTED PARALLEL +# 29E4; EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE +# 29E5; IDENTICAL TO AND SLANTED PARALLEL +# 29E8; DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK +# 29E9; DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK +# 29F4; RULE-DELAYED +# 29F6; SOLIDUS WITH OVERBAR +# 29F7; REVERSE SOLIDUS WITH HORIZONTAL STROKE +# 2A0A; MODULO TWO SUM +# 2A0B; SUMMATION WITH INTEGRAL +# 2A0C; QUADRUPLE INTEGRAL OPERATOR +# 2A0D; FINITE PART INTEGRAL +# 2A0E; INTEGRAL WITH DOUBLE STROKE +# 2A0F; INTEGRAL AVERAGE WITH SLASH +# 2A10; CIRCULATION FUNCTION +# 2A11; ANTICLOCKWISE INTEGRATION +# 2A12; LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE +# 2A13; LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE +# 2A14; LINE INTEGRATION NOT INCLUDING THE POLE +# 2A15; INTEGRAL AROUND A POINT OPERATOR +# 2A16; QUATERNION INTEGRAL OPERATOR +# 2A17; INTEGRAL WITH LEFTWARDS ARROW WITH HOOK +# 2A18; INTEGRAL WITH TIMES SIGN +# 2A19; INTEGRAL WITH INTERSECTION +# 2A1A; INTEGRAL WITH UNION +# 2A1B; INTEGRAL WITH OVERBAR +# 2A1C; INTEGRAL WITH UNDERBAR +# 2A1E; LARGE LEFT TRIANGLE OPERATOR +# 2A1F; Z NOTATION SCHEMA COMPOSITION +# 2A20; Z NOTATION SCHEMA PIPING +# 2A21; Z NOTATION SCHEMA PROJECTION +# 2A24; PLUS SIGN WITH TILDE ABOVE +# 2A26; PLUS SIGN WITH TILDE BELOW +# 2A29; MINUS SIGN WITH COMMA ABOVE +# 2A3E; Z NOTATION RELATIONAL COMPOSITION +# 2A57; SLOPING LARGE OR +# 2A58; SLOPING LARGE AND +# 2A6A; TILDE OPERATOR WITH DOT ABOVE +# 2A6B; TILDE OPERATOR WITH RISING DOTS +# 2A6C; SIMILAR MINUS SIMILAR +# 2A6D; CONGRUENT WITH DOT ABOVE +# 2A6F; ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT +# 2A70; APPROXIMATELY EQUAL OR EQUAL TO +# 2A73; EQUALS SIGN ABOVE TILDE OPERATOR +# 2A74; DOUBLE COLON EQUAL +# 2A7B; LESS-THAN WITH QUESTION MARK ABOVE +# 2A7C; GREATER-THAN WITH QUESTION MARK ABOVE +# 2A85; LESS-THAN OR APPROXIMATE +# 2A86; GREATER-THAN OR APPROXIMATE +# 2A87; LESS-THAN AND SINGLE-LINE NOT EQUAL TO +# 2A88; GREATER-THAN AND SINGLE-LINE NOT EQUAL TO +# 2A89; LESS-THAN AND NOT APPROXIMATE +# 2A8A; GREATER-THAN AND NOT APPROXIMATE +# 2A8D; LESS-THAN ABOVE SIMILAR OR EQUAL +# 2A8E; GREATER-THAN ABOVE SIMILAR OR EQUAL +# 2A8F; LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN +# 2A90; GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN +# 2A9D; SIMILAR OR LESS-THAN +# 2A9E; SIMILAR OR GREATER-THAN +# 2A9F; SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN +# 2AA0; SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN +# 2AA3; DOUBLE NESTED LESS-THAN WITH UNDERBAR +# 2AB1; PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO +# 2AB2; SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO +# 2AB5; PRECEDES ABOVE NOT EQUAL TO +# 2AB6; SUCCEEDS ABOVE NOT EQUAL TO +# 2AB7; PRECEDES ABOVE ALMOST EQUAL TO +# 2AB8; SUCCEEDS ABOVE ALMOST EQUAL TO +# 2AB9; PRECEDES ABOVE NOT ALMOST EQUAL TO +# 2ABA; SUCCEEDS ABOVE NOT ALMOST EQUAL TO +# 2AC7; SUBSET OF ABOVE TILDE OPERATOR +# 2AC8; SUPERSET OF ABOVE TILDE OPERATOR +# 2AC9; SUBSET OF ABOVE ALMOST EQUAL TO +# 2ACA; SUPERSET OF ABOVE ALMOST EQUAL TO +# 2ACB; SUBSET OF ABOVE NOT EQUAL TO +# 2ACC; SUPERSET OF ABOVE NOT EQUAL TO +# 2ADC; FORKING +# 2AE2; VERTICAL BAR TRIPLE RIGHT TURNSTILE +# 2AE6; LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL +# 2AEE; DOES NOT DIVIDE WITH REVERSED NEGATION SLASH +# 2AF3; PARALLEL WITH TILDE OPERATOR +# 2AFB; TRIPLE SOLIDUS BINARY RELATION +# 2AFD; DOUBLE SOLIDUS OPERATOR +# 1D6DB; MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +# 1D715; MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +# 1D74F; MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +# 1D789; MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +# 1D7C3; MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL + +# EOF diff --git a/util/UnicodeData.txt b/unicode/UnicodeData.txt similarity index 100% rename from util/UnicodeData.txt rename to unicode/UnicodeData.txt From e83200d891a4513bf3cf20e7c23d95c685ce297e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Mar 2010 23:33:42 +0100 Subject: [PATCH 088/503] mention variations and vertical text in unsupported features --- normal/charset.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/normal/charset.c b/normal/charset.c index 00bbcb815..c026c6966 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -33,6 +33,8 @@ 218, 224, 226, 233, 234 - Private use surrogates - Private use characters (not really a problem) + - Variations (no font support) + - Vertical text */ /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE From 03e4ef0293b15b6623cdbab36d09aa13bc123f55 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Mar 2010 00:35:38 +0100 Subject: [PATCH 089/503] Import data for arabic joining computation --- autogen.sh | 2 +- include/grub/unicode.h | 31 +++- unicode/ArabicShaping.txt | 373 ++++++++++++++++++++++++++++++++++++++ util/import_unicode.py | 48 ++++- 4 files changed, 445 insertions(+), 9 deletions(-) create mode 100644 unicode/ArabicShaping.txt diff --git a/autogen.sh b/autogen.sh index 7cbee5cca..f9d55318f 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,7 +13,7 @@ echo timestamp > stamp-h.in python util/import_gcry.py lib/libgcrypt/ . -python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unidata.c +python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt unidata.c for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do if test -e $rmk ; then diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 457bcd93b..28c752b9e 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -36,6 +36,7 @@ struct grub_unicode_compact_range grub_uint8_t bidi_type:5; grub_uint8_t comb_type; grub_uint8_t bidi_mirror:1; + grub_uint8_t join_type:3; } __attribute__ ((packed)); enum grub_bidi_type @@ -61,6 +62,16 @@ enum grub_bidi_type GRUB_BIDI_TYPE_ON }; +enum grub_join_type + { + GRUB_JOIN_TYPE_NONJOINING = 0, + GRUB_JOIN_TYPE_LEFT = 1, + GRUB_JOIN_TYPE_RIGHT = 2, + GRUB_JOIN_TYPE_DUAL = 3, + GRUB_JOIN_TYPE_CAUSING = 4, + GRUB_JOIN_TYPE_TRANSPARENT = 5 + }; + enum grub_comb_type { GRUB_UNICODE_COMB_NONE = 0, @@ -103,7 +114,7 @@ struct grub_unicode_glyph { grub_uint32_t base; grub_uint16_t variant:9; - grub_uint8_t attributes:1; + grub_uint8_t attributes:5; grub_size_t ncomb; struct grub_unicode_combining { grub_uint32_t code; @@ -115,12 +126,30 @@ struct grub_unicode_glyph }; #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 +#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT 1 +#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED 0x2 +#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \ + (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \ + << GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT) +/* Set iff the corresponding joining flags come from ZWJ or ZWNJ. */ +#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT 0x8 +#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT \ + (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \ + << GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT) +#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN \ + (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \ + | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \ + | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \ + | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT) + #define GRUB_UNICODE_COMBINING_GRAPHEME_JOINER 0x34f #define GRUB_UNICODE_VARIATION_SELECTOR_1 0xfe00 #define GRUB_UNICODE_VARIATION_SELECTOR_16 0xfe0f #define GRUB_UNICODE_VARIATION_SELECTOR_17 0xe0100 #define GRUB_UNICODE_VARIATION_SELECTOR_256 0xe01ef #define GRUB_UNICODE_HEBREW_WAW 0x05d5 +#define GRUB_UNICODE_ZWNJ 0x200c +#define GRUB_UNICODE_ZWJ 0x200d extern struct grub_unicode_compact_range grub_unicode_compact[]; extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; diff --git a/unicode/ArabicShaping.txt b/unicode/ArabicShaping.txt new file mode 100644 index 000000000..b851d3839 --- /dev/null +++ b/unicode/ArabicShaping.txt @@ -0,0 +1,373 @@ +# ArabicShaping-5.2.0.txt +# Date: 2009-08-17, 11:11:00 PDT [KW] +# +# This file is a normative contributory data file in the +# Unicode Character Database. +# +# Copyright (c) 1991-2009 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# This file defines the shaping classes for Arabic, Syriac, and N'Ko +# positional shaping, repeating in machine readable form the +# information exemplified in Tables 8-3, 8-7, 8-8, 8-11, 8-12, +# 8-13, and 13-5 of The Unicode Standard, Version 5.2. +# +# See sections 8.2, 8.3, and 13.5 of The Unicode Standard, Version 5.2 +# for more information. +# +# Each line contains four fields, separated by a semicolon. +# +# Field 0: the code point, in 4-digit hexadecimal +# form, of an Arabic, Syriac, or N'Ko character. +# +# Field 1: gives a short schematic name for that character, +# abbreviated from the normative Unicode character name. +# +# Field 2: defines the joining type (property name: Joining_Type) +# R Right_Joining +# L Left_Joining +# D Dual_Joining +# C Join_Causing +# U Non_Joining +# T Transparent +# See Section 8.2, Arabic for more information on these types. +# +# Field 3: defines the joining group (property name: Joining_Group) +# +# The values of the joining group are based schematically on character +# names. Where a schematic character name consists of two or more parts separated +# by spaces, the formal Joining_Group property value, as specified in +# PropertyValueAliases.txt, consists of the same name parts joined by +# underscores. Hence, the entry: +# +# 0629; TEH MARBUTA; R; TEH MARBUTA +# +# corresponds to [Joining_Group = Teh_Marbuta]. +# +# Note: For historical reasons, the property value [Joining_Group = Hamza_On_Heh_Goal] +# is anachronistically named. It used to apply to both of the following characters +# in earlier versions of the standard: +# +# U+06C2 ARABIC LETTER HEH GOAL WITH HAMZA ABOVE +# U+06C3 ARABIC LETTER TEH MARBUTA GOAL +# +# However, it currently applies only to U+06C3, and *not* to U+06C2. +# To avoid destabilizing existing Joining_Group property aliases, the +# value Hamza_On_Heh_Goal has not been changed, despite the fact that it +# no longer applies to Hamza On Heh Goal, but only to Teh Marbuta Goal. +# +# When other cursive scripts are added to the Unicode Standard in +# the future, the joining group value of all its letters will default +# to jg=No_Joining_Group in this data file. Other, more specific +# joining group values will be defined only if an explicit proposal +# to define those values exactly has been approved by the UTC. This +# is the convention exemplified by the N'Ko script. Only the Arabic +# and Syriac scripts currently have explicit joining group values defined. +# +# Note: Code points that are not explicitly listed in this file are +# either of joining type T or U: +# +# - Those that not explicitly listed that are of General Category Mn, Me, or Cf +# have joining type T. +# - All others not explicitly listed have joining type U. +# +# For an explicit listing of characters of joining type T, see +# the derived property file DerivedJoiningType.txt. +# +# There are currently no characters of joining type L defined in Unicode. +# +# ############################################################# + +# Unicode; Schematic Name; Joining Type; Joining Group + +# Arabic characters + +0600; ARABIC NUMBER SIGN; U; No_Joining_Group +0601; ARABIC SIGN SANAH; U; No_Joining_Group +0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group +0603; ARABIC SIGN SAFHA; U; No_Joining_Group +0608; ARABIC RAY; U; No_Joining_Group +060B; AFGHANI SIGN; U; No_Joining_Group +0621; HAMZA; U; No_Joining_Group +0622; MADDA ON ALEF; R; ALEF +0623; HAMZA ON ALEF; R; ALEF +0624; HAMZA ON WAW; R; WAW +0625; HAMZA UNDER ALEF; R; ALEF +0626; HAMZA ON YEH; D; YEH +0627; ALEF; R; ALEF +0628; BEH; D; BEH +0629; TEH MARBUTA; R; TEH MARBUTA +062A; TEH; D; BEH +062B; THEH; D; BEH +062C; JEEM; D; HAH +062D; HAH; D; HAH +062E; KHAH; D; HAH +062F; DAL; R; DAL +0630; THAL; R; DAL +0631; REH; R; REH +0632; ZAIN; R; REH +0633; SEEN; D; SEEN +0634; SHEEN; D; SEEN +0635; SAD; D; SAD +0636; DAD; D; SAD +0637; TAH; D; TAH +0638; ZAH; D; TAH +0639; AIN; D; AIN +063A; GHAIN; D; AIN +063B; KEHEH WITH 2 DOTS ABOVE; D; GAF +063C; KEHEH WITH 3 DOTS BELOW; D; GAF +063D; FARSI YEH WITH INVERTED V; D; FARSI YEH +063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH +063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH +0640; TATWEEL; C; No_Joining_Group +0641; FEH; D; FEH +0642; QAF; D; QAF +0643; KAF; D; KAF +0644; LAM; D; LAM +0645; MEEM; D; MEEM +0646; NOON; D; NOON +0647; HEH; D; HEH +0648; WAW; R; WAW +0649; ALEF MAKSURA; D; YEH +064A; YEH; D; YEH +066E; DOTLESS BEH; D; BEH +066F; DOTLESS QAF; D; QAF +0671; HAMZAT WASL ON ALEF; R; ALEF +0672; WAVY HAMZA ON ALEF; R; ALEF +0673; WAVY HAMZA UNDER ALEF; R; ALEF +0674; HIGH HAMZA; U; No_Joining_Group +0675; HIGH HAMZA ALEF; R; ALEF +0676; HIGH HAMZA WAW; R; WAW +0677; HIGH HAMZA WAW WITH DAMMA; R; WAW +0678; HIGH HAMZA YEH; D; YEH +0679; TEH WITH SMALL TAH; D; BEH +067A; TEH WITH 2 DOTS VERTICAL ABOVE; D; BEH +067B; BEH WITH 2 DOTS VERTICAL BELOW; D; BEH +067C; TEH WITH RING; D; BEH +067D; TEH WITH 3 DOTS ABOVE DOWNWARD; D; BEH +067E; TEH WITH 3 DOTS BELOW; D; BEH +067F; TEH WITH 4 DOTS ABOVE; D; BEH +0680; BEH WITH 4 DOTS BELOW; D; BEH +0681; HAMZA ON HAH; D; HAH +0682; HAH WITH 2 DOTS VERTICAL ABOVE; D; HAH +0683; HAH WITH MIDDLE 2 DOTS; D; HAH +0684; HAH WITH MIDDLE 2 DOTS VERTICAL; D; HAH +0685; HAH WITH 3 DOTS ABOVE; D; HAH +0686; HAH WITH MIDDLE 3 DOTS DOWNWARD; D; HAH +0687; HAH WITH MIDDLE 4 DOTS; D; HAH +0688; DAL WITH SMALL TAH; R; DAL +0689; DAL WITH RING; R; DAL +068A; DAL WITH DOT BELOW; R; DAL +068B; DAL WITH DOT BELOW AND SMALL TAH; R; DAL +068C; DAL WITH 2 DOTS ABOVE; R; DAL +068D; DAL WITH 2 DOTS BELOW; R; DAL +068E; DAL WITH 3 DOTS ABOVE; R; DAL +068F; DAL WITH 3 DOTS ABOVE DOWNWARD; R; DAL +0690; DAL WITH 4 DOTS ABOVE; R; DAL +0691; REH WITH SMALL TAH; R; REH +0692; REH WITH SMALL V; R; REH +0693; REH WITH RING; R; REH +0694; REH WITH DOT BELOW; R; REH +0695; REH WITH SMALL V BELOW; R; REH +0696; REH WITH DOT BELOW AND DOT ABOVE; R; REH +0697; REH WITH 2 DOTS ABOVE; R; REH +0698; REH WITH 3 DOTS ABOVE; R; REH +0699; REH WITH 4 DOTS ABOVE; R; REH +069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN +069B; SEEN WITH 3 DOTS BELOW; D; SEEN +069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN +069D; SAD WITH 2 DOTS BELOW; D; SAD +069E; SAD WITH 3 DOTS ABOVE; D; SAD +069F; TAH WITH 3 DOTS ABOVE; D; TAH +06A0; AIN WITH 3 DOTS ABOVE; D; AIN +06A1; DOTLESS FEH; D; FEH +06A2; FEH WITH DOT MOVED BELOW; D; FEH +06A3; FEH WITH DOT BELOW; D; FEH +06A4; FEH WITH 3 DOTS ABOVE; D; FEH +06A5; FEH WITH 3 DOTS BELOW; D; FEH +06A6; FEH WITH 4 DOTS ABOVE; D; FEH +06A7; QAF WITH DOT ABOVE; D; QAF +06A8; QAF WITH 3 DOTS ABOVE; D; QAF +06A9; KEHEH; D; GAF +06AA; SWASH KAF; D; SWASH KAF +06AB; KAF WITH RING; D; GAF +06AC; KAF WITH DOT ABOVE; D; KAF +06AD; KAF WITH 3 DOTS ABOVE; D; KAF +06AE; KAF WITH 3 DOTS BELOW; D; KAF +06AF; GAF; D; GAF +06B0; GAF WITH RING; D; GAF +06B1; GAF WITH 2 DOTS ABOVE; D; GAF +06B2; GAF WITH 2 DOTS BELOW; D; GAF +06B3; GAF WITH 2 DOTS VERTICAL BELOW; D; GAF +06B4; GAF WITH 3 DOTS ABOVE; D; GAF +06B5; LAM WITH SMALL V; D; LAM +06B6; LAM WITH DOT ABOVE; D; LAM +06B7; LAM WITH 3 DOTS ABOVE; D; LAM +06B8; LAM WITH 3 DOTS BELOW; D; LAM +06B9; NOON WITH DOT BELOW; D; NOON +06BA; DOTLESS NOON; D; NOON +06BB; DOTLESS NOON WITH SMALL TAH; D; NOON +06BC; NOON WITH RING; D; NOON +06BD; NYA; D; NYA +06BE; KNOTTED HEH; D; KNOTTED HEH +06BF; HAH WITH MIDDLE 3 DOTS DOWNWARD AND DOT ABOVE; D; HAH +06C0; HAMZA ON HEH; R; TEH MARBUTA +06C1; HEH GOAL; D; HEH GOAL +06C2; HAMZA ON HEH GOAL; D; HEH GOAL +06C3; TEH MARBUTA GOAL; R; HAMZA ON HEH GOAL +06C4; WAW WITH RING; R; WAW +06C5; WAW WITH BAR; R; WAW +06C6; WAW WITH SMALL V; R; WAW +06C7; WAW WITH DAMMA; R; WAW +06C8; WAW WITH ALEF ABOVE; R; WAW +06C9; WAW WITH INVERTED SMALL V; R; WAW +06CA; WAW WITH 2 DOTS ABOVE; R; WAW +06CB; WAW WITH 3 DOTS ABOVE; R; WAW +06CC; FARSI YEH; D; FARSI YEH +06CD; YEH WITH TAIL; R; YEH WITH TAIL +06CE; FARSI YEH WITH SMALL V; D; FARSI YEH +06CF; WAW WITH DOT ABOVE; R; WAW +06D0; YEH WITH 2 DOTS VERTICAL BELOW; D; YEH +06D1; YEH WITH 3 DOTS BELOW; D; YEH +06D2; YEH BARREE; R; YEH BARREE +06D3; HAMZA ON YEH BARREE; R; YEH BARREE +06D5; AE; R; TEH MARBUTA +06DD; ARABIC END OF AYAH; U; No_Joining_Group +06EE; DAL WITH INVERTED V; R; DAL +06EF; REH WITH INVERTED V; R; REH +06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN +06FB; DAD WITH DOT BELOW; D; SAD +06FC; GHAIN WITH DOT BELOW; D; AIN +06FF; HEH WITH INVERTED V; D; KNOTTED HEH + +# Syriac characters + +0710; ALAPH; R; ALAPH +0712; BETH; D; BETH +0713; GAMAL; D; GAMAL +0714; GAMAL GARSHUNI; D; GAMAL +0715; DALATH; R; DALATH RISH +0716; DOTLESS DALATH RISH; R; DALATH RISH +0717; HE; R; HE +0718; WAW; R; SYRIAC WAW +0719; ZAIN; R; ZAIN +071A; HETH; D; HETH +071B; TETH; D; TETH +071C; TETH GARSHUNI; D; TETH +071D; YUDH; D; YUDH +071E; YUDH HE; R; YUDH HE +071F; KAPH; D; KAPH +0720; LAMADH; D; LAMADH +0721; MIM; D; MIM +0722; NUN; D; NUN +0723; SEMKATH; D; SEMKATH +0724; FINAL SEMKATH; D; FINAL SEMKATH +0725; E; D; E +0726; PE; D; PE +0727; REVERSED PE; D; REVERSED PE +0728; SADHE; R; SADHE +0729; QAPH; D; QAPH +072A; RISH; R; DALATH RISH +072B; SHIN; D; SHIN +072C; TAW; R; TAW +072D; PERSIAN BHETH; D; BETH +072E; PERSIAN GHAMAL; D; GAMAL +072F; PERSIAN DHALATH; R; DALATH RISH +074D; SOGDIAN ZHAIN; R; ZHAIN +074E; SOGDIAN KHAPH; D; KHAPH +074F; SOGDIAN FE; D; FE + +# Arabic supplement characters + +0750; BEH WITH 3 DOTS HORIZONTALLY BELOW; D; BEH +0751; BEH WITH DOT BELOW AND 3 DOTS ABOVE; D; BEH +0752; BEH WITH 3 DOTS POINTING UPWARDS BELOW; D; BEH +0753; BEH WITH 3 DOTS POINTING UPWARDS BELOW AND 2 DOTS ABOVE; D; BEH +0754; BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH +0755; BEH WITH INVERTED SMALL V BELOW; D; BEH +0756; BEH WITH SMALL V; D; BEH +0757; HAH WITH 2 DOTS ABOVE; D; HAH +0758; HAH WITH 3 DOTS POINTING UPWARDS BELOW; D; HAH +0759; DAL WITH 2 DOTS VERTICALLY BELOW AND SMALL TAH; R; DAL +075A; DAL WITH INVERTED SMALL V BELOW; R; DAL +075B; REH WITH STROKE; R; REH +075C; SEEN WITH 4 DOTS ABOVE; D; SEEN +075D; AIN WITH 2 DOTS ABOVE; D; AIN +075E; AIN WITH 3 DOTS POINTING DOWNWARDS ABOVE; D; AIN +075F; AIN WITH 2 DOTS VERTICALLY ABOVE; D; AIN +0760; FEH WITH 2 DOTS BELOW; D; FEH +0761; FEH WITH 3 DOTS POINTING UPWARDS BELOW; D; FEH +0762; KEHEH WITH DOT ABOVE; D; GAF +0763; KEHEH WITH 3 DOTS ABOVE; D; GAF +0764; KEHEH WITH 3 DOTS POINTING UPWARDS BELOW; D; GAF +0765; MEEM WITH DOT ABOVE; D; MEEM +0766; MEEM WITH DOT BELOW; D; MEEM +0767; NOON WITH 2 DOTS BELOW; D; NOON +0768; NOON WITH SMALL TAH; D; NOON +0769; NOON WITH SMALL V; D; NOON +076A; LAM WITH BAR; D; LAM +076B; REH WITH 2 DOTS VERTICALLY ABOVE; R; REH +076C; REH WITH HAMZA ABOVE; R; REH +076D; SEEN WITH 2 DOTS VERTICALLY ABOVE; D; SEEN +076E; HAH WITH SMALL TAH BELOW; D; HAH +076F; HAH WITH SMALL TAH AND 2 DOTS; D; HAH +0770; SEEN WITH SMALL TAH AND 2 DOTS; D; SEEN +0771; REH WITH SMALL TAH AND 2 DOTS; R; REH +0772; HAH WITH SMALL TAH ABOVE; D; HAH +0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF +0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF +0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH +0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH +0777; YEH WITH DIGIT FOUR BELOW; D; YEH +0778; WAW WITH DIGIT TWO ABOVE; R; WAW +0779; WAW WITH DIGIT THREE ABOVE; R; WAW +077A; YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE +077B; YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE +077C; HAH WITH DIGIT FOUR BELOW; D; HAH +077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN +077E; SEEN WITH INVERTED V; D; SEEN +077F; KAF WITH 2 DOTS ABOVE; D; KAF + +# N'Ko Characters + +07CA; NKO A; D; No_Joining_Group +07CB; NKO EE; D; No_Joining_Group +07CC; NKO I; D; No_Joining_Group +07CD; NKO E; D; No_Joining_Group +07CE; NKO U; D; No_Joining_Group +07CF; NKO OO; D; No_Joining_Group +07D0; NKO O; D; No_Joining_Group +07D1; NKO DAGBASINNA; D; No_Joining_Group +07D2; NKO N; D; No_Joining_Group +07D3; NKO BA; D; No_Joining_Group +07D4; NKO PA; D; No_Joining_Group +07D5; NKO TA; D; No_Joining_Group +07D6; NKO JA; D; No_Joining_Group +07D7; NKO CHA; D; No_Joining_Group +07D8; NKO DA; D; No_Joining_Group +07D9; NKO RA; D; No_Joining_Group +07DA; NKO RRA; D; No_Joining_Group +07DB; NKO SA; D; No_Joining_Group +07DC; NKO GBA; D; No_Joining_Group +07DD; NKO FA; D; No_Joining_Group +07DE; NKO KA; D; No_Joining_Group +07DF; NKO LA; D; No_Joining_Group +07E0; NKO NA WOLOSO; D; No_Joining_Group +07E1; NKO MA; D; No_Joining_Group +07E2; NKO NYA; D; No_Joining_Group +07E3; NKO NA; D; No_Joining_Group +07E4; NKO HA; D; No_Joining_Group +07E5; NKO WA; D; No_Joining_Group +07E6; NKO YA; D; No_Joining_Group +07E7; NKO NYA WOLOSO; D; No_Joining_Group +07E8; NKO JONA JA; D; No_Joining_Group +07E9; NKO JONA CHA; D; No_Joining_Group +07EA; NKO JONA RA; D; No_Joining_Group +07FA; NKO LAJANYALAN; C; No_Joining_Group + +# Other + +200C; ZERO WIDTH NON-JOINER; U; No_Joining_Group +200D; ZERO WIDTH JOINER; C; No_Joining_Group + +# EOF diff --git a/util/import_unicode.py b/util/import_unicode.py index e0e53b655..653d7bae2 100644 --- a/util/import_unicode.py +++ b/util/import_unicode.py @@ -24,8 +24,33 @@ import datetime if len (sys.argv) < 3: print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) exit (0) +infile = open (sys.argv[3], "r") +joining = {} +for line in infile: + line = re.sub ("#.*$", "", line) + line = line.replace ("\n", "") + line = line.replace (" ", "") + if len (line) == 0 or line[0] == '\n': + continue + sp = line.split (";") + curcode = int (sp[0], 16) + if sp[2] == "U": + joining[curcode] = "GRUB_JOIN_TYPE_NONJOINING" + elif sp[2] == "L": + joining[curcode] = "GRUB_JOIN_TYPE_LEFT" + elif sp[2] == "R": + joining[curcode] = "GRUB_JOIN_TYPE_RIGHT" + elif sp[2] == "D": + joining[curcode] = "GRUB_JOIN_TYPE_DUAL" + elif sp[2] == "C": + joining[curcode] = "GRUB_JOIN_TYPE_CAUSING" + else: + print ("Unknown joining type '%s'" % sp[2]) + exit (1) +infile.close () + infile = open (sys.argv[1], "r") -outfile = open (sys.argv[3], "w") +outfile = open (sys.argv[4], "w") outfile.write ("#include \n") outfile.write ("\n") outfile.write ("struct grub_unicode_compact_range grub_unicode_compact[] = {\n") @@ -74,23 +99,32 @@ for line in infile: curcombtype != 240 and curcombtype != 253 and \ curcombtype != 254 and curcombtype != 255): print ("WARNING: Unknown combining type %d" % curcombtype) + if curcode in joining: + curjoin = joining[curcode] + elif sp[2] == "Me" or sp[2] == "Mn" or sp[2] == "Cf": + curjoin = "GRUB_JOIN_TYPE_TRANSPARENT" + else: + curjoin = "GRUB_JOIN_TYPE_NONJOINING" if lastcode + 1 != curcode or curbiditype != lastbiditype \ - or curcombtype != lastcombtype or curmirrortype != lastmirrortype: + or curcombtype != lastcombtype or curmirrortype != lastmirrortype \ + or curjoin != lastjoin: if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0 or \ lastmirrortype): - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d},\n" \ + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, %s},\n" \ % (begincode, lastcode, lastbiditype, \ - lastcombtype, lastmirrortype))) + lastcombtype, lastmirrortype, \ + lastjoin))) begincode = curcode lastcode = curcode + lastjoin = curjoin lastbiditype = curbiditype lastcombtype = curcombtype lastmirrortype = curmirrortype if lastbiditype != "L" or lastcombtype != 0 or lastmirrortype: - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d},\n" \ + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, %s},\n" \ % (begincode, lastcode, lastbiditype, lastcombtype, \ - lastmirrortype))) -outfile.write ("{0, 0, 0, 0, 0},\n") + lastmirrortype, lastjoin))) +outfile.write ("{0, 0, 0, 0, 0, 0},\n") outfile.write ("};\n") From df3d4cba13cdc9d6f3f45ad5446df537ac7ccc73 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Mar 2010 01:00:54 +0100 Subject: [PATCH 090/503] Arabic joining computation --- normal/charset.c | 225 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 197 insertions(+), 28 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index c026c6966..970a14b1f 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -403,6 +403,26 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, return p - dest; } +static grub_uint8_t *join_types = NULL; + +static void +unpack_join (void) +{ + unsigned i; + struct grub_unicode_compact_range *cur; + + join_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (!join_types) + { + grub_errno = GRUB_ERR_NONE; + return; + } + for (cur = grub_unicode_compact; cur->end; cur++) + for (i = cur->start; i <= cur->end + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + join_types[i] = cur->join_type; +} + static grub_uint8_t *bidi_types = NULL; static void @@ -444,6 +464,24 @@ get_bidi_type (grub_uint32_t c) return GRUB_BIDI_TYPE_L; } +static inline enum grub_join_type +get_join_type (grub_uint32_t c) +{ + struct grub_unicode_compact_range *cur; + + if (!join_types) + unpack_join (); + + if (join_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return join_types[c]; + + for (cur = grub_unicode_compact; cur->end; cur++) + if (cur->start <= c && c <= cur->end) + return cur->join_type; + + return GRUB_JOIN_TYPE_NONJOINING; +} + static inline int is_mirrored (grub_uint32_t c) { @@ -637,8 +675,6 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, { unsigned min_odd_level = 0xffffffff; unsigned max_level = 0; - unsigned j; - unsigned i; if (k != visual_len && last_space > (signed) line_start) k = last_space; @@ -650,30 +686,113 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, else last_space_width = line_width - last_width; - for (i = line_start; i < k; i++) - { - if (levels[i] > max_level) - max_level = levels[i]; - if (levels[i] < min_odd_level && (levels[i] & 1)) - min_odd_level = levels[i]; - } + { + unsigned i; + for (i = line_start; i < k; i++) + { + if (levels[i] > max_level) + max_level = levels[i]; + if (levels[i] < min_odd_level && (levels[i] & 1)) + min_odd_level = levels[i]; + } + } + + { + unsigned j; + /* FIXME: can be optimized. */ + for (j = max_level; j >= min_odd_level; j--) + { + unsigned in = 0; + unsigned i; + for (i = line_start; i < k; i++) + { + if (i != line_start && levels[i] >= j && levels[i-1] < j) + in = i; + if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) + revert (in, i); + } + } + } - /* FIXME: can be optimized. */ - for (j = max_level; j >= min_odd_level; j--) - { - unsigned in = 0; - for (i = line_start; i < k; i++) - { - if (i != line_start && levels[i] >= j && levels[i-1] < j) - in = i; - if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) - revert (in, i); - } - } - - for (i = line_start; i < k; i++) - if (is_mirrored (visual[i].base) && levels[i]) - visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + { + unsigned i; + for (i = line_start; i < k; i++) + { + if (is_mirrored (visual[i].base) && levels[i]) + visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + if ((visual[i].attributes & GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN) + && levels[i]) + { + int left, right; + left = visual[i].attributes + & (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED + | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT); + right = visual[i].attributes + & (GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED + | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT); + visual[i].attributes &= ~GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN; + left <<= GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT; + right >>= GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT; + visual[i].attributes |= (left | right); + } + } + } + + { + int left_join = 0; + unsigned i; + for (i = line_start; i < k; i++) + { + enum grub_join_type join_type = get_join_type (visual[i].base); + if (!(visual[i].attributes + & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT) + && (join_type == GRUB_JOIN_TYPE_LEFT + || join_type == GRUB_JOIN_TYPE_DUAL)) + { + if (left_join) + visual[i].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + else + visual[i].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + } + if (join_type == GRUB_JOIN_TYPE_NONJOINING + || join_type == GRUB_JOIN_TYPE_LEFT) + left_join = 0; + if (join_type == GRUB_JOIN_TYPE_RIGHT + || join_type == GRUB_JOIN_TYPE_DUAL + || join_type == GRUB_JOIN_TYPE_CAUSING) + left_join = 1; + } + } + + { + int right_join = 0; + signed i; + for (i = k - 1; i >= (signed) line_start; i--) + { + enum grub_join_type join_type = get_join_type (visual[i].base); + if (!(visual[i].attributes + & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT) + && (join_type == GRUB_JOIN_TYPE_RIGHT + || join_type == GRUB_JOIN_TYPE_DUAL)) + { + if (right_join) + visual[i].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + else + visual[i].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + } + if (join_type == GRUB_JOIN_TYPE_NONJOINING + || join_type == GRUB_JOIN_TYPE_RIGHT) + right_join = 0; + if (join_type == GRUB_JOIN_TYPE_LEFT + || join_type == GRUB_JOIN_TYPE_DUAL + || join_type == GRUB_JOIN_TYPE_CAUSING) + right_join = 1; + } + } grub_memcpy (outptr, &visual[line_start], (k - line_start) * sizeof (visual[0])); @@ -785,11 +904,43 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, cur_override = OVERRIDE_NEUTRAL; { const grub_uint32_t *lptr; + enum {JOIN_DEFAULT, NOJOIN, JOIN_FORCE} join_state = JOIN_DEFAULT; + int zwj_propagate_to_previous = 0; for (lptr = logical; lptr < logical + logical_len;) { - grub_size_t p = grub_unicode_aglomerate_comb (lptr, logical - + logical_len - lptr, - &visual[visual_len]); + grub_size_t p; + + if (*lptr == GRUB_UNICODE_ZWJ) + { + if (zwj_propagate_to_previous) + { + visual[visual_len - 1].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT + | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + } + zwj_propagate_to_previous = 0; + join_state = JOIN_FORCE; + lptr++; + continue; + } + + if (*lptr == GRUB_UNICODE_ZWNJ) + { + if (zwj_propagate_to_previous) + { + visual[visual_len - 1].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT; + visual[visual_len - 1].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + } + zwj_propagate_to_previous = 0; + join_state = NOJOIN; + lptr++; + continue; + } + + p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr, + &visual[visual_len]); type = get_bidi_type (visual[visual_len].base); switch (type) @@ -813,6 +964,24 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, break; default: { + if (join_state == JOIN_FORCE) + { + visual[visual_len].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT + | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + } + + if (join_state == NOJOIN) + { + visual[visual_len].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT; + visual[visual_len].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + } + + join_state = JOIN_DEFAULT; + zwj_propagate_to_previous = 1; + levels[visual_len] = cur_level; if (cur_override != OVERRIDE_NEUTRAL) resolved_types[visual_len] = From b320771ada9a62d43cfae4d2e37dead01ffe23ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Mar 2010 01:05:50 +0100 Subject: [PATCH 091/503] Remove private use surrogates from unsupported list --- normal/charset.c | 1 - 1 file changed, 1 deletion(-) diff --git a/normal/charset.c b/normal/charset.c index 970a14b1f..c3a856b97 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -31,7 +31,6 @@ - Combining characters of types 7, 8, 9, 21, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 84, 91, 103, 107, 118, 122, 129, 130, 132, 218, 224, 226, 233, 234 - - Private use surrogates - Private use characters (not really a problem) - Variations (no font support) - Vertical text From 0761327dd08f78b749f82290497aa0ef20a38a21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Mar 2010 20:03:29 +0100 Subject: [PATCH 092/503] Update unicode problem list --- normal/charset.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index c3a856b97..0683fc88c 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -19,14 +19,15 @@ /* Current problems with Unicode rendering: - B and BN bidi type characters (ignored) - - Mc type characters with combining class 0 (treated as non-combining) - - Mn type characters with combining class 0 (treated as non-combining) - - Me type characters with combining class 0 (treated as non-combining) + - Mc type characters with combining class 0 (poorly combined) + - Mn type characters with combining class 0 (poorly combined) + - Me type characters with combining class 0 (poorly combined) - Cf type characters (ignored) - Cc type characters (ignored) - Line-breaking rules (e.g. Zs type characters) - Indic languages - Arabic shaping + - non-Semitic shaping (rarely used) - Zl and Zp characters - Combining characters of types 7, 8, 9, 21, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 84, 91, 103, 107, 118, 122, 129, 130, 132, @@ -34,6 +35,11 @@ - Private use characters (not really a problem) - Variations (no font support) - Vertical text + Font information ignored: + - Kerning + - Justification data + - Glyph posititioning + - Baseline data */ /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE From e6d428c1b8a5414b6ae79af023c45822df45a9f5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Mar 2010 22:33:00 +0100 Subject: [PATCH 093/503] Arabic shaping support --- font/font.c | 22 ++- include/grub/font.h | 5 + normal/charset.c | 2 +- util/grub-mkfont.c | 423 +++++++++++++++++++++++++++++++++++++++----- 4 files changed, 400 insertions(+), 52 deletions(-) diff --git a/font/font.c b/font/font.c index 1fc10aa91..911ca4ee3 100644 --- a/font/font.c +++ b/font/font.c @@ -151,6 +151,7 @@ ascii_glyph_lookup (grub_uint32_t code) ascii_font_glyph[current]->offset_x = 0; ascii_font_glyph[current]->offset_y = -2; ascii_font_glyph[current]->device_width = 8; + ascii_font_glyph[current]->font = NULL; grub_memcpy (ascii_font_glyph[current]->bitmap, &ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE], @@ -1181,11 +1182,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, { grub_int16_t space = 0; /* Center by default. */ - grub_int16_t targetx = (bounds.width - combining_glyphs[i]->width) / 2 - + bounds.x; + grub_int16_t targetx; if (!combining_glyphs[i]) continue; + targetx = (bounds.width - combining_glyphs[i]->width) / 2 + + bounds.x; /* CGJ is to avoid diacritics reordering. */ if (glyph_id->combining[i].code == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) continue; @@ -1325,13 +1327,25 @@ grub_font_construct_dry_run (grub_font_t hinted_font, struct grub_font_glyph ***combining_glyphs_out, int *device_width) { - struct grub_font_glyph *main_glyph; + struct grub_font_glyph *main_glyph = NULL; struct grub_font_glyph **combining_glyphs; + grub_uint32_t desired_attributes = 0; if (combining_glyphs_out) *combining_glyphs_out = NULL; - main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base); + if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED) + desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED; + + if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED) + desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED; + + main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base + | desired_attributes); + + if (!main_glyph) + main_glyph = grub_font_get_glyph_with_fallback (hinted_font, + glyph_id->base); /* Glyph not available in any font. Use ASCII fallback. */ if (!main_glyph) diff --git a/include/grub/font.h b/include/grub/font.h index b896159c2..690363faf 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -70,6 +70,11 @@ struct grub_font_glyph grub_uint8_t bitmap[0]; }; +/* Part of code field which is really used as such. */ +#define GRUB_FONT_CODE_CHAR_MASK 0x001fffff +#define GRUB_FONT_CODE_RIGHT_JOINED 0x80000000 +#define GRUB_FONT_CODE_LEFT_JOINED 0x40000000 + /* Initialize the font loader. Must be called before any fonts are loaded or used. */ void grub_font_loader_init (void); diff --git a/normal/charset.c b/normal/charset.c index 0683fc88c..9ad1f7cb7 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -26,7 +26,6 @@ - Cc type characters (ignored) - Line-breaking rules (e.g. Zs type characters) - Indic languages - - Arabic shaping - non-Semitic shaping (rarely used) - Zl and Zp characters - Combining characters of types 7, 8, 9, 21, 27, 28, 29, 30, 31, @@ -40,6 +39,7 @@ - Justification data - Glyph posititioning - Baseline data + TODO: Use form characters of Unicode as last resort Arabic shaping. */ /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 49c5095ac..9eee2a488 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -19,8 +19,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -29,6 +31,8 @@ #include #include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_TRUETYPE_TABLES_H #include #include "progname.h" @@ -47,7 +51,7 @@ struct grub_glyph_info int y_ofs; int device_width; int bitmap_size; - grub_uint8_t bitmap[0]; + grub_uint8_t *bitmap; }; enum file_formats @@ -76,7 +80,9 @@ struct grub_font_info int flags; int num_range; grub_uint32_t *ranges; - struct grub_glyph_info *glyph; + struct grub_glyph_info *glyphs_unsorted; + struct grub_glyph_info *glyphs_sorted; + int num_glyphs; }; static struct option options[] = @@ -149,11 +155,11 @@ add_pixel (grub_uint8_t **data, int *mask, int not_blank) *mask >>= 1; } -void -add_char (struct grub_font_info *font_info, FT_Face face, - grub_uint32_t char_code) +static void +add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, + grub_uint32_t char_code) { - struct grub_glyph_info *glyph_info, **p_glyph; + struct grub_glyph_info *glyph_info; int width, height; grub_uint8_t *data; int mask, i, j, bitmap_size; @@ -168,24 +174,17 @@ add_char (struct grub_font_info *font_info, FT_Face face, else if (font_info->flags & GRUB_FONT_FLAG_FORCEHINT) flag |= FT_LOAD_FORCE_AUTOHINT; - if (FT_Load_Char (face, char_code, flag)) - return; + if (FT_Load_Glyph (face, glyph_idx, flag)) + { + printf ("WARNING: Couldn't load glyph %x\n", glyph_idx); + 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; - if (glyph->next) printf ("%x\n", char_code); @@ -193,11 +192,13 @@ add_char (struct grub_font_info *font_info, FT_Face face, height = glyph->bitmap.rows; bitmap_size = ((width * height + 7) / 8); - glyph_info = xmalloc (sizeof (struct grub_glyph_info) + bitmap_size); + glyph_info = xmalloc (sizeof (struct grub_glyph_info)); + glyph_info->bitmap = xmalloc (bitmap_size); glyph_info->bitmap_size = bitmap_size; - glyph_info->next = *p_glyph; - *p_glyph = glyph_info; + glyph_info->next = font_info->glyphs_unsorted; + font_info->glyphs_unsorted = glyph_info; + font_info->num_glyphs++; glyph_info->char_code = char_code; glyph_info->width = width; @@ -227,9 +228,318 @@ add_char (struct grub_font_info *font_info, FT_Face face, (1 << (7 - (i & 7)))); } +struct glyph_replace *subst_rightjoin, *subst_leftjoin, *subst_medijoin; + +struct glyph_replace +{ + struct glyph_replace *next; + grub_uint32_t from, to; +}; + +/* TODO: sort glyph_replace and use binary search if necessary. */ +static void +add_char (struct grub_font_info *font_info, FT_Face face, + grub_uint32_t char_code) +{ + FT_UInt glyph_idx; + struct glyph_replace *cur; + + glyph_idx = FT_Get_Char_Index (face, char_code); + if (!glyph_idx) + return; + add_glyph (font_info, glyph_idx, face, char_code); + for (cur = subst_rightjoin; cur; cur = cur->next) + if (cur->from == glyph_idx) + { + add_glyph (font_info, cur->to, face, + char_code | GRUB_FONT_CODE_RIGHT_JOINED); + break; + } + for (cur = subst_leftjoin; cur; cur = cur->next) + if (cur->from == glyph_idx) + { + add_glyph (font_info, cur->to, face, + char_code | GRUB_FONT_CODE_LEFT_JOINED); + break; + } + for (cur = subst_medijoin; cur; cur = cur->next) + if (cur->from == glyph_idx) + { + add_glyph (font_info, cur->to, face, + char_code | GRUB_FONT_CODE_LEFT_JOINED + | GRUB_FONT_CODE_RIGHT_JOINED); + break; + } +} + +struct gsub_header +{ + grub_uint32_t version; + grub_uint16_t scripts_off; + grub_uint16_t features_off; + grub_uint16_t lookups_off; +} __attribute__ ((packed)); + +struct gsub_features +{ + grub_uint16_t count; + struct + { +#define FEATURE_FINA 0x66696e61 +#define FEATURE_INIT 0x696e6974 +#define FEATURE_MEDI 0x6d656469 +#define FEATURE_AALT 0x61616c74 + grub_uint32_t feature_tag; + grub_uint16_t offset; + } __attribute__ ((packed)) features[0]; +} __attribute__ ((packed)); + +struct gsub_feature +{ + grub_uint16_t params; + grub_uint16_t lookupcount; + grub_uint16_t lookupindices[0]; +} __attribute__ ((packed)); + +struct gsub_lookup_list +{ + grub_uint16_t count; + grub_uint16_t offsets[0]; +} __attribute__ ((packed)); + +struct gsub_lookup +{ + grub_uint16_t type; + grub_uint16_t flag; + grub_uint16_t subtablecount; + grub_uint16_t subtables[0]; +} __attribute__ ((packed)); + +struct gsub_substitution +{ + grub_uint16_t type; + grub_uint16_t coverage_off; + union + { + grub_int16_t delta; + struct + { + grub_int16_t count; + grub_uint16_t repl[0]; + }; + }; +} __attribute__ ((packed)); + +struct gsub_coverage_list +{ + grub_uint16_t type; + grub_uint16_t count; + grub_uint16_t glyphs[0]; +} __attribute__ ((packed)); + +struct gsub_coverage_ranges +{ + grub_uint16_t type; + grub_uint16_t count; + struct + { + grub_uint16_t start; + grub_uint16_t end; + grub_uint16_t start_index; + } __attribute__ ((packed)) ranges[0]; +} __attribute__ ((packed)); + +#define GSUB_SINGLE_SUBSTITUTION 1 + +#define GSUB_SUBSTITUTION_DELTA 1 +#define GSUB_SUBSTITUTION_MAP 2 + +#define GSUB_COVERAGE_LIST 1 +#define GSUB_COVERAGE_RANGE 2 + +#define GSUB_RTL_CHAR 1 + +static void +add_subst (grub_uint32_t from, grub_uint32_t to, struct glyph_replace **target) +{ + struct glyph_replace *new = xmalloc (sizeof (*new)); + new->next = *target; + new->from = from; + new->to = to; + *target = new; +} + +static void +process_cursive (struct gsub_feature *feature, + struct gsub_lookup_list *lookups, + grub_uint32_t feattag) +{ + int j, k; + int i; + struct glyph_replace **target; + struct gsub_substitution *sub; + + auto inline void subst (grub_uint32_t glyph); + void subst (grub_uint32_t glyph) + { + grub_uint16_t substtype; + substtype = grub_be_to_cpu16 (sub->type); + + if (substtype == GSUB_SUBSTITUTION_DELTA) + add_subst (glyph, glyph + grub_be_to_cpu16 (sub->delta), target); + else if (i >= grub_be_to_cpu16 (sub->count)) + printf ("Out of range substitution (%d, %d)\n", i, + grub_be_to_cpu16 (sub->count)); + else + add_subst (glyph, grub_be_to_cpu16 (sub->repl[i++]), target); + } + + for (j = 0; j < grub_be_to_cpu16 (feature->lookupcount); j++) + { + int lookup_index = grub_be_to_cpu16 (feature->lookupindices[j]); + struct gsub_lookup *lookup; + if (lookup_index >= grub_be_to_cpu16 (lookups->count)) + { + printf ("Out of range lookup: %d\n", lookup_index); + continue; + } + lookup = (struct gsub_lookup *) + ((grub_uint8_t *) lookups + + grub_be_to_cpu16 (lookups->offsets[lookup_index])); + if (grub_be_to_cpu16 (lookup->type) != GSUB_SINGLE_SUBSTITUTION) + { + printf ("Unsupported substitution type: %d\n", + grub_be_to_cpu16 (lookup->type)); + continue; + } + if (grub_be_to_cpu16 (lookup->flag) & ~GSUB_RTL_CHAR) + { + printf ("Unsupported substitution flag: 0x%x\n", + grub_be_to_cpu16 (lookup->flag)); + } + switch (feattag) + { + case FEATURE_INIT: + if (grub_be_to_cpu16 (lookup->flag) & GSUB_RTL_CHAR) + target = &subst_leftjoin; + else + target = &subst_rightjoin; + break; + case FEATURE_FINA: + if (grub_be_to_cpu16 (lookup->flag) & GSUB_RTL_CHAR) + target = &subst_rightjoin; + else + target = &subst_leftjoin; + break; + case FEATURE_MEDI: + target = &subst_medijoin; + break; + } + for (k = 0; k < grub_be_to_cpu16 (lookup->subtablecount); k++) + { + sub = (struct gsub_substitution *) + ((grub_uint8_t *) lookup + grub_be_to_cpu16 (lookup->subtables[k])); + grub_uint16_t substtype; + substtype = grub_be_to_cpu16 (sub->type); + if (substtype != GSUB_SUBSTITUTION_MAP + && substtype != GSUB_SUBSTITUTION_DELTA) + { + printf ("Unsupported substitution specification: %d\n", + substtype); + continue; + } + void *coverage = (grub_uint8_t *) sub + + grub_be_to_cpu16 (sub->coverage_off); + grub_uint32_t covertype; + covertype = grub_be_to_cpu16 (*(grub_uint16_t * __attribute__ ((packed))) coverage); + i = 0; + if (covertype == GSUB_COVERAGE_LIST) + { + struct gsub_coverage_list *cover = coverage; + int l; + for (l = 0; l < grub_be_to_cpu16 (cover->count); l++) + subst (grub_be_to_cpu16 (cover->glyphs[l])); + } + else if (covertype == GSUB_COVERAGE_RANGE) + { + struct gsub_coverage_ranges *cover = coverage; + int l, m; + for (l = 0; l < grub_be_to_cpu16 (cover->count); l++) + for (m = grub_be_to_cpu16 (cover->ranges[l].start); + m <= grub_be_to_cpu16 (cover->ranges[l].end); m++) + subst (m); + } + else + printf ("Unsupported coverage specification: %d\n", covertype); + } + } +} + void add_font (struct grub_font_info *font_info, FT_Face face) { + struct gsub_header *gsub = NULL; + FT_ULong gsub_len = 0; + + if (!FT_Load_Sfnt_Table (face, TTAG_GSUB, 0, NULL, &gsub_len)) + { + gsub = xmalloc (gsub_len); + if (FT_Load_Sfnt_Table (face, TTAG_GSUB, 0, (void *) gsub, &gsub_len)) + { + free (gsub); + gsub = NULL; + gsub_len = 0; + } + } + if (gsub) + { + struct gsub_features *features + = (struct gsub_features *) (((grub_uint8_t *) gsub) + + grub_be_to_cpu16 (gsub->features_off)); + struct gsub_lookup_list *lookups + = (struct gsub_lookup_list *) (((grub_uint8_t *) gsub) + + grub_be_to_cpu16 (gsub->lookups_off)); + int i; + int nfeatures = grub_be_to_cpu16 (features->count); + for (i = 0; i < nfeatures; i++) + { + struct gsub_feature *feature = (struct gsub_feature *) + ((grub_uint8_t *) features + + grub_be_to_cpu16 (features->features[i].offset)); + grub_uint32_t feattag + = grub_be_to_cpu32 (features->features[i].feature_tag); + if (feature->params) + printf ("WARNING: unsupported feature parameters: %x\n", + grub_be_to_cpu16 (feature->params)); + switch (feattag) + { + /* Used for retrieving all possible variants. Useless in grub. */ + case FEATURE_AALT: + break; + + /* Cursive form variants. */ + case FEATURE_FINA: + case FEATURE_INIT: + case FEATURE_MEDI: + process_cursive (feature, lookups, feattag); + break; + + default: + { + char str[5]; + int j; + memcpy (str, &features->features[i].feature_tag, + sizeof (features->features[i].feature_tag)); + str[4] = 0; + for (j = 0; j < 4; j++) + if (!grub_isgraph (str[j])) + str[j] = '?'; + printf ("Unknown gsub feature 0x%x (%s)\n", feattag, str); + } + } + } + } + if (font_info->num_range) { int i; @@ -287,7 +597,8 @@ print_glyphs (struct grub_font_info *font_info) struct grub_glyph_info *glyph; char line[512]; - for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++) + for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs; + glyph++, num++) { int x, y, xmax, xmin, ymax, ymin; grub_uint8_t *bitmap, mask; @@ -363,7 +674,8 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file) grub_util_error ("Can\'t write to file %s.", output_file); int correct_size; - for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++) + for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs; + glyph++, num++) { correct_size = 1; if (glyph->width != 8 || glyph->height != 16) @@ -397,7 +709,8 @@ write_font_width_spec (struct grub_font_info *font_info, char *output_file) if (! file) grub_util_error ("Can\'t write to file %s.", output_file); - for (glyph = font_info->glyph; glyph; glyph = glyph->next) + for (glyph = font_info->glyphs_sorted; + glyph < font_info->glyphs_sorted + font_info->num_glyphs; glyph++) if (glyph->width > 12) out[glyph->char_code >> 3] |= (1 << (glyph->char_code & 7)); @@ -412,8 +725,8 @@ write_font_pf2 (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; + int offset; + struct grub_glyph_info *cur; file = fopen (output_file, "wb"); if (! file) @@ -497,33 +810,18 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) 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); + printf ("Number of glyph: %d\n", font_info->num_glyphs); - leng = grub_cpu_to_be32 (num * 9); + leng = grub_cpu_to_be32 (font_info->num_glyphs * 9); grub_util_write_image (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX, sizeof(FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - 1, file); grub_util_write_image ((char *) &leng, 4, file); - offset += 8 + num * 9 + 8; + offset += 8 + font_info->num_glyphs * 9 + 8; - for (cur = font_info->glyph; cur; cur = cur->next) + for (cur = font_info->glyphs_sorted; + cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++) { data = grub_cpu_to_be32 (cur->char_code); grub_util_write_image ((char *) &data, 4, file); @@ -539,7 +837,8 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) sizeof(FONT_FORMAT_SECTION_NAMES_DATA) - 1, file); grub_util_write_image ((char *) &leng, 4, file); - for (cur = font_info->glyph; cur; cur = cur->next) + for (cur = font_info->glyphs_sorted; + cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++) { data = grub_cpu_to_be16 (cur->width); grub_util_write_image ((char *) &data, 2, file); @@ -742,6 +1041,36 @@ main (int argc, char *argv[]) FT_Done_FreeType (ft_lib); + { + int counter[65537]; + struct grub_glyph_info *tmp, *cur; + int i; + + memset (counter, 0, sizeof (counter)); + + for (cur = font_info.glyphs_unsorted; cur; cur = cur->next) + counter[(cur->char_code & 0xffff) + 1]++; + for (i = 0; i < 0x10000; i++) + counter[i+1] += counter[i]; + tmp = xmalloc (font_info.num_glyphs + * sizeof (tmp[0])); + for (cur = font_info.glyphs_unsorted; cur; cur = cur->next) + tmp[counter[(cur->char_code & 0xffff)]++] = *cur; + + memset (counter, 0, sizeof (counter)); + + for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++) + counter[((cur->char_code & 0xffff0000) >> 16) + 1]++; + for (i = 0; i < 0x10000; i++) + counter[i+1] += counter[i]; + font_info.glyphs_sorted = xmalloc (font_info.num_glyphs + * sizeof (font_info.glyphs_sorted[0])); + for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++) + font_info.glyphs_sorted[counter[(cur->char_code & 0xffff0000) >> 16]++] + = *cur; + free (tmp); + } + switch (file_format) { case PF2: From 6d107fb2a41045d5ba6fd6b37b35aa3973140340 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 25 Mar 2010 11:26:50 +0100 Subject: [PATCH 094/503] Add ligatures to problem list --- font/font.c | 2 -- normal/charset.c | 1 + util/grub-mkfont.c | 7 +++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/font/font.c b/font/font.c index 911ca4ee3..f39bd9e7e 100644 --- a/font/font.c +++ b/font/font.c @@ -1268,8 +1268,6 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, case GRUB_UNICODE_COMB_HEBREW_QAMATS: case GRUB_UNICODE_COMB_HEBREW_TSERE: case GRUB_UNICODE_COMB_HEBREW_SEGOL: - /* , - GRUB_UNICODE_COMB_HEBREW_DAGESH = 21*/ /* TODO: placement in final kaf and under reish. */ case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL: diff --git a/normal/charset.c b/normal/charset.c index 9ad1f7cb7..55a9894a9 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -34,6 +34,7 @@ - Private use characters (not really a problem) - Variations (no font support) - Vertical text + - Ligatures Font information ignored: - Kerning - Justification data diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 9eee2a488..09a03085a 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -289,6 +289,8 @@ struct gsub_features #define FEATURE_INIT 0x696e6974 #define FEATURE_MEDI 0x6d656469 #define FEATURE_AALT 0x61616c74 +#define FEATURE_LIGA 0x6c696761 +#define FEATURE_RLIG 0x726c6967 grub_uint32_t feature_tag; grub_uint16_t offset; } __attribute__ ((packed)) features[0]; @@ -517,6 +519,11 @@ add_font (struct grub_font_info *font_info, FT_Face face) case FEATURE_AALT: break; + /* FIXME: Add ligature support. */ + case FEATURE_LIGA: + case FEATURE_RLIG: + break; + /* Cursive form variants. */ case FEATURE_FINA: case FEATURE_INIT: From 3c31d9c0824926fed5c3513812e13c0641867fed Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 25 Mar 2010 11:56:19 +0100 Subject: [PATCH 095/503] Report freetype errors --- util/grub-mkfont.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 09a03085a..c9d48ed7a 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -35,6 +35,12 @@ #include FT_TRUETYPE_TABLES_H #include +#undef __FTERRORS_H__ +#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { +#define FT_ERRORDEF(e, v, s) [e] = s, +#define FT_ERROR_END_LIST }; +#include FT_ERRORS_H + #include "progname.h" #define GRUB_FONT_DEFAULT_SIZE 16 @@ -165,6 +171,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, int mask, i, j, bitmap_size; FT_GlyphSlot glyph; int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME; + FT_Error err; if (font_info->flags & GRUB_FONT_FLAG_NOBITMAP) flag |= FT_LOAD_NO_BITMAP; @@ -174,9 +181,15 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, else if (font_info->flags & GRUB_FONT_FLAG_FORCEHINT) flag |= FT_LOAD_FORCE_AUTOHINT; - if (FT_Load_Glyph (face, glyph_idx, flag)) + err = FT_Load_Glyph (face, glyph_idx, flag); + if (err) { - printf ("WARNING: Couldn't load glyph %x\n", glyph_idx); + if (err < ARRAY_SIZE (ft_errmsgs)) + printf ("Freetype Error %d loading glyph 0x%x for U+0x%x: %s\n", + err, glyph_idx, char_code, ft_errmsgs[err]); + else + printf ("Freetype Error %d loading glyph 0x%x for U+0x%x\n", + err, glyph_idx, char_code); return; } From d85da27cc0e1e670abee72758836f633cd52b297 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:14:24 +0100 Subject: [PATCH 096/503] Remove grub_commands_iterate --- commands/help.c | 145 ++++++++++++++++++++--------------------- include/grub/command.h | 7 +- normal/completion.c | 29 ++++----- 3 files changed, 82 insertions(+), 99 deletions(-) diff --git a/commands/help.c b/commands/help.c index 1181c3bfb..ecf77fa4c 100644 --- a/commands/help.c +++ b/commands/help.c @@ -33,94 +33,87 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, 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 ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && - (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) - { - struct grub_term_output *term; - const char *summary_translated = _(cmd->summary); - char *command_help; - grub_uint32_t *unicode_command_help; - grub_uint32_t *unicode_last_position; - - command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); - if (!command_help) - return 1; - - grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, - &unicode_last_position); - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - unsigned stringwidth; - grub_uint32_t *unicode_last_screen_position; - - unicode_last_screen_position = unicode_command_help; - - stringwidth = 0; - - while (unicode_last_screen_position < unicode_last_position && - stringwidth < ((grub_term_width (term) / 2) - 2)) - { - stringwidth - += grub_term_getcharwidth (term, - *unicode_last_screen_position); - unicode_last_screen_position++; - } - - grub_print_ucs4 (unicode_command_help, - unicode_last_screen_position, term); - if (!(cnt % 2)) - grub_print_spaces (term, grub_term_width (term) / 2 - - stringwidth); - } - if (cnt % 2) - grub_printf ("\n"); - cnt++; - - grub_free (command_help); - grub_free (unicode_command_help); - } - return 0; - } - - int print_command_help (grub_command_t cmd) - { - if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) - { - if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg))) - { - if (cnt++ > 0) - grub_printf ("\n\n"); - - if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) - grub_arg_show_help ((grub_extcmd_t) cmd->data); - else - grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), - _(cmd->description)); - } - } - return 0; - } - if (argc == 0) { - grub_command_iterate (print_command_info); + grub_command_t cmd; + FOR_COMMANDS(cmd) + { + if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && + (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) + { + struct grub_term_output *term; + const char *summary_translated = _(cmd->summary); + char *command_help; + grub_uint32_t *unicode_command_help; + grub_uint32_t *unicode_last_position; + + command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); + if (!command_help) + break; + + grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, + &unicode_last_position); + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + unsigned stringwidth; + grub_uint32_t *unicode_last_screen_position; + + unicode_last_screen_position = unicode_command_help; + + stringwidth = 0; + + while (unicode_last_screen_position < unicode_last_position && + stringwidth < ((grub_term_width (term) / 2) - 2)) + { + stringwidth + += grub_term_getcharwidth (term, + *unicode_last_screen_position); + unicode_last_screen_position++; + } + + grub_print_ucs4 (unicode_command_help, + unicode_last_screen_position, term); + if (!(cnt % 2)) + grub_print_spaces (term, grub_term_width (term) / 2 + - stringwidth); + } + if (cnt % 2) + grub_printf ("\n"); + cnt++; + + grub_free (command_help); + grub_free (unicode_command_help); + } + } if (!(cnt % 2)) grub_printf ("\n"); } else { int i; + grub_command_t cmd; for (i = 0; i < argc; i++) { currarg = args[i]; - grub_command_iterate (print_command_help); + FOR_COMMANDS(cmd) + { + if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) + { + if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg))) + { + if (cnt++ > 0) + grub_printf ("\n\n"); + + if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) + grub_arg_show_help ((grub_extcmd_t) cmd->data); + else + grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), + _(cmd->description)); + } + } + } } } diff --git a/include/grub/command.h b/include/grub/command.h index 6e9942b60..3fad88ed0 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -115,12 +115,7 @@ grub_command_execute (const char *name, int argc, char **argv) return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND; } -static inline int -grub_command_iterate (int (*func) (grub_command_t)) -{ - return grub_list_iterate (GRUB_AS_LIST (grub_command_list), - (grub_list_hook_t) func); -} +#define FOR_COMMANDS(var) for ((var) = grub_command_list; (var); (var) = (var)->next) void grub_register_core_commands (void); diff --git a/normal/completion.c b/normal/completion.c index 13e8f7a6b..13c4b7b05 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -176,21 +176,6 @@ iterate_dev (const char *devname) return 0; } -static int -iterate_command (grub_command_t cmd) -{ - if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) - { - 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) @@ -421,8 +406,18 @@ grub_normal_do_completion (char *buf, int *restore, if (argc == 1 || argc == 0) { /* Complete a command. */ - if (grub_command_iterate (iterate_command)) - goto fail; + grub_command_t cmd; + FOR_COMMANDS(cmd) + { + if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) + { + if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE) + { + if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND)) + goto fail; + } + } + } } else if (*current_word == '-') { From fbc5a383e2742ffdf166ddcd98e12e87999aecf4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:18:19 +0100 Subject: [PATCH 097/503] Remove list_iterate usage auth.c --- normal/auth.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/normal/auth.c b/normal/auth.c index 156b84c37..6d475cc0a 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -133,25 +133,24 @@ static int is_authenticated (const char *userlist) { const char *superusers; - - auto int hook (grub_list_t item); - int hook (grub_list_t item) - { - const char *name; - if (!((struct grub_auth_user *) item)->authenticated) - return 0; - name = ((struct grub_auth_user *) item)->name; - - return (userlist && grub_strword (userlist, name)) - || grub_strword (superusers, name); - } + struct grub_auth_user *user; superusers = grub_env_get ("superusers"); if (!superusers) return 1; - return grub_list_iterate (GRUB_AS_LIST (users), hook); + for (user = users; user; user = user->next) + { + if (!(user->authenticated)) + continue; + + if ((userlist && grub_strword (userlist, user->name)) + || grub_strword (superusers, user->name)) + return 1; + } + + return 0; } static int From 2aa6398b64430fc5235361b69efbae56e0188aec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:21:01 +0100 Subject: [PATCH 098/503] Remove second part of list_iterate usage auth.c --- normal/auth.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/normal/auth.c b/normal/auth.c index 6d475cc0a..87337afda 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -204,22 +204,7 @@ grub_auth_check_authentication (const char *userlist) grub_err_t err; static unsigned long punishment_delay = 1; char entered[GRUB_AUTH_MAX_PASSLEN]; - - auto int hook (grub_list_t item); - int hook (grub_list_t item) - { - if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0) - cur = (struct grub_auth_user *) item; - return 0; - } - - auto int hook_any (grub_list_t item); - int hook_any (grub_list_t item) - { - if (((struct grub_auth_user *) item)->callback) - cur = (struct grub_auth_user *) item; - return 0; - } + struct grub_auth_user *user; grub_memset (login, 0, sizeof (login)); @@ -239,7 +224,11 @@ grub_auth_check_authentication (const char *userlist) if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) goto access_denied; - grub_list_iterate (GRUB_AS_LIST (users), hook); + for (user = users; user; user = user->next) + { + if (grub_strcmp (login, user->name) == 0) + cur = user; + } if (!cur || ! cur->callback) goto access_denied; From 7c0ab99bd2095fdd081e5c627727a3c878b35409 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:23:19 +0100 Subject: [PATCH 099/503] Remove list_iterate usage functional_test.c --- tests/lib/functional_test.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 8ff08cf8a..33eeec451 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -26,15 +26,10 @@ grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - auto int run_test (grub_test_t test); - int run_test (grub_test_t test) - { - grub_test_run (test); - return 0; - } + grub_test_t test; - grub_list_iterate (GRUB_AS_LIST (grub_test_list), - (grub_list_hook_t) run_test); + for (test = grub_test_list; test; test = test->next) + grub_test_run (test); return GRUB_ERR_NONE; } From 42ca71ca47cbd9b83c9febee2a6a1950c0fcd58f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:25:53 +0100 Subject: [PATCH 100/503] FOR_LIST_ELEMENTS convenience macros --- include/grub/list.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grub/list.h b/include/grub/list.h index 5559158dc..1c00a349e 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -40,6 +40,8 @@ int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook); void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, grub_list_test_t test); +#define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) + static inline void * grub_bad_type_cast_real (int line, const char *file) ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); From 3f8ae91c0913ec34baea73adb4368a44a41e9416 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:32:21 +0100 Subject: [PATCH 101/503] Use FOR_LIST_ELEMENTS convenience macros --- include/grub/command.h | 2 +- include/grub/partition.h | 2 +- include/grub/term.h | 8 ++++---- normal/auth.c | 2 +- tests/lib/functional_test.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/grub/command.h b/include/grub/command.h index 3fad88ed0..6bd3d07c9 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -115,7 +115,7 @@ grub_command_execute (const char *name, int argc, char **argv) return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND; } -#define FOR_COMMANDS(var) for ((var) = grub_command_list; (var); (var) = (var)->next) +#define FOR_COMMANDS(var) FOR_LIST_ELEMENTS((var), grub_command_list) void grub_register_core_commands (void); diff --git a/include/grub/partition.h b/include/grub/partition.h index 80a9c15f0..722c7b3e0 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -91,7 +91,7 @@ grub_partition_map_unregister (grub_partition_map_t partmap) GRUB_AS_LIST (partmap)); } -#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next) +#define FOR_PARTITION_MAPS(var) FOR_LIST_ELEMENTS((var), (grub_partition_map_list)) static inline grub_disk_addr_t diff --git a/include/grub/term.h b/include/grub/term.h index 143aabe1e..230436388 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -245,10 +245,10 @@ grub_term_unregister_output (grub_term_output_t term) GRUB_AS_LIST (term)); } -#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next) -#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next) -#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next) -#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next) +#define FOR_ACTIVE_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs)) +#define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs_disabled)) +#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) +#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, diff --git a/normal/auth.c b/normal/auth.c index 87337afda..c28f50024 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -140,7 +140,7 @@ is_authenticated (const char *userlist) if (!superusers) return 1; - for (user = users; user; user = user->next) + FOR_LIST_ELEMENTS (user, users) { if (!(user->authenticated)) continue; diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 33eeec451..6aafe4dbb 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -28,7 +28,7 @@ grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), { grub_test_t test; - for (test = grub_test_list; test; test = test->next) + FOR_LIST_ELEMENTS (test, grub_test_list) grub_test_run (test); return GRUB_ERR_NONE; } From 41e12098274d28183aa5f46d0c26863383f5b26d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:35:34 +0100 Subject: [PATCH 102/503] Remove list_iterate usage tests/ --- tests/lib/test.c | 20 +++++++------------- tests/lib/unit_test.c | 12 ++++-------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/tests/lib/test.c b/tests/lib/test.c index b5c054370..3029495c6 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -134,23 +134,17 @@ grub_test_unregister (const char *name) int grub_test_run (grub_test_t test) { - auto int print_failure (grub_test_failure_t item); - int print_failure (grub_test_failure_t item) - { - grub_test_failure_t failure = (grub_test_failure_t) item; - - grub_printf (" %s:%s:%u: %s\n", - (failure->file ? : ""), - (failure->funp ? : ""), - failure->line, (failure->message ? : "")); - return 0; - } + grub_test_failure_t failure; test->main (); grub_printf ("%s:\n", test->name); - grub_list_iterate (GRUB_AS_LIST (failure_list), - (grub_list_hook_t) print_failure); + FOR_LIST_ELEMENTS (failure, failure_list) + grub_printf (" %s:%s:%u: %s\n", + (failure->file ? : ""), + (failure->funp ? : ""), + failure->line, (failure->message ? : "")); + if (!failure_list) grub_printf ("%s: PASS\n", test->name); else diff --git a/tests/lib/unit_test.c b/tests/lib/unit_test.c index e461150de..e8b97b1f4 100644 --- a/tests/lib/unit_test.c +++ b/tests/lib/unit_test.c @@ -34,16 +34,12 @@ main (int argc __attribute__ ((unused)), extern void grub_unit_test_init (void); extern void grub_unit_test_fini (void); - auto int run_test (grub_test_t test); - int run_test (grub_test_t test) - { - status = grub_test_run (test) ? : status; - return 0; - } + grub_test_t test; grub_unit_test_init (); - grub_list_iterate (GRUB_AS_LIST (grub_test_list), - (grub_list_hook_t) run_test); + FOR_LIST_ELEMENTS (test, grub_test_list) + status = grub_test_run (test) ? : status; + grub_unit_test_fini (); exit (status); From fda282327f5c373d2c4ffd8c2b3080d09d742af8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:44:18 +0100 Subject: [PATCH 103/503] Complete eradication of grub_list_iterate --- commands/handler.c | 30 ++++++++++++++++-------------- include/grub/list.h | 1 - kern/list.c | 31 +++++-------------------------- normal/handler.c | 42 ++++++++++++++++-------------------------- 4 files changed, 37 insertions(+), 67 deletions(-) diff --git a/commands/handler.c b/commands/handler.c index f9270972b..2bfa67415 100644 --- a/commands/handler.c +++ b/commands/handler.c @@ -32,21 +32,17 @@ grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), void *curr_item = 0; grub_handler_class_t head; - auto int list_item (grub_named_list_t item); - int list_item (grub_named_list_t item) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - - return 0; - } - head = grub_handler_class_list; if (argc == 0) { - grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item); + grub_handler_class_t item; + FOR_LIST_ELEMENTS(item, head) + { + if (item == curr_item) + grub_putchar ('*'); + + grub_printf ("%s\n", item->name); + } } else { @@ -63,9 +59,15 @@ grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), if (argc == 0) { + grub_handler_class_t item; curr_item = class->cur_handler; - grub_list_iterate (GRUB_AS_LIST (class->handler_list), - (grub_list_hook_t) list_item); + FOR_LIST_ELEMENTS(item, head) + { + if (item == curr_item) + grub_putchar ('*'); + + grub_printf ("%s\n", item->name); + } } else { diff --git a/include/grub/list.h b/include/grub/list.h index 1c00a349e..2fd418aca 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -36,7 +36,6 @@ typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); -int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook); void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, grub_list_test_t test); diff --git a/kern/list.c b/kern/list.c index 379b0d886..507d13f86 100644 --- a/kern/list.c +++ b/kern/list.c @@ -53,18 +53,6 @@ grub_list_remove (grub_list_t *head, grub_list_t item) } } -int -grub_list_iterate (grub_list_t head, grub_list_hook_t hook) -{ - grub_list_t p; - - for (p = head; p; p = p->next) - if (hook (p)) - return 1; - - return 0; -} - void grub_list_insert (grub_list_t *head, grub_list_t item, grub_list_test_t test) @@ -82,22 +70,13 @@ grub_list_insert (grub_list_t *head, grub_list_t item, void * grub_named_list_find (grub_named_list_t head, const char *name) { - grub_named_list_t result = NULL; + grub_named_list_t item; - auto int list_find (grub_named_list_t item); - int list_find (grub_named_list_t item) - { - if (! grub_strcmp (item->name, name)) - { - result = item; - return 1; - } + FOR_LIST_ELEMENTS (item, head) + if (grub_strcmp (item->name, name) == 0) + return item; - return 0; - } - - grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_find); - return result; + return NULL; } void diff --git a/normal/handler.c b/normal/handler.c index 686626929..8c97fd9a8 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -138,30 +138,6 @@ read_handler_list (void) static int first_time = 1; const char *class_name; - auto int iterate_handler (grub_handler_t handler); - int iterate_handler (grub_handler_t handler) - { - char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; - - grub_strcpy (name, class_name); - grub_strcat (name, "."); - grub_strcat (name, handler->name); - - insert_handler (name, 0); - - return 0; - } - - auto int iterate_class (grub_handler_class_t class); - int iterate_class (grub_handler_class_t class) - { - class_name = class->name; - grub_list_iterate (GRUB_AS_LIST (class->handler_list), - (grub_list_hook_t) iterate_handler); - - return 0; - } - /* Make sure that this function does not get executed twice. */ if (! first_time) return; @@ -209,8 +185,22 @@ read_handler_list (void) } } - grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list), - (grub_list_hook_t) iterate_class); + grub_handler_class_t class; + FOR_LIST_ELEMENTS (class, grub_handler_class_list) + { + grub_handler_t handler; + class_name = class->name; + FOR_LIST_ELEMENTS(handler, class->handler_list) + { + char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; + + grub_strcpy (name, class_name); + grub_strcat (name, "."); + grub_strcat (name, handler->name); + + insert_handler (name, 0); + } + } /* Ignore errors. */ grub_errno = GRUB_ERR_NONE; From 82f542016ebd7bd31ce2b74085b22e5f4ead49af Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:00:06 +0100 Subject: [PATCH 104/503] Eradicate grub_list_insert --- include/grub/list.h | 2 -- kern/list.c | 39 ++++++++++++++------------------------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/include/grub/list.h b/include/grub/list.h index 2fd418aca..73d51be12 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -36,8 +36,6 @@ typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); -void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, - grub_list_test_t test); #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) diff --git a/kern/list.c b/kern/list.c index 507d13f86..5b0248129 100644 --- a/kern/list.c +++ b/kern/list.c @@ -53,20 +53,6 @@ grub_list_remove (grub_list_t *head, grub_list_t item) } } -void -grub_list_insert (grub_list_t *head, grub_list_t item, - grub_list_test_t test) -{ - grub_list_t *p, q; - - for (p = head, q = *p; q; p = &(q->next), q = q->next) - if (test (item, q)) - break; - - *p = item; - item->next = q; -} - void * grub_named_list_find (grub_named_list_t head, const char *name) { @@ -84,27 +70,30 @@ grub_prio_list_insert (grub_prio_list_t *head, grub_prio_list_t nitem) { int inactive = 0; - auto int test (grub_prio_list_t new_item, grub_prio_list_t item); - int test (grub_prio_list_t new_item, grub_prio_list_t item) + grub_prio_list_t *p, q; + + for (p = head, q = *p; q; p = &(q->next), q = q->next) { int r; - r = grub_strcmp (new_item->name, item->name); - if (r) - return (r < 0); + r = grub_strcmp (nitem->name, q->name); + if (r < 0) + break; + if (r > 0) + continue; - if (new_item->prio >= (item->prio & GRUB_PRIO_LIST_PRIO_MASK)) + if (nitem->prio >= (q->prio & GRUB_PRIO_LIST_PRIO_MASK)) { - item->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE; - return 1; + q->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE; + break; } inactive = 1; - return 0; } - grub_list_insert (GRUB_AS_LIST_P (head), GRUB_AS_LIST (nitem), - (grub_list_test_t) test); + *p = nitem; + nitem->next = q; + if (! inactive) nitem->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE; } From 8cfa78770df70c60637fddc12749b256382eca7d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:05:25 +0100 Subject: [PATCH 105/503] cleanup list.h a bit --- include/grub/list.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/grub/list.h b/include/grub/list.h index 73d51be12..d3abd69c4 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -30,9 +30,6 @@ struct grub_list }; typedef struct grub_list *grub_list_t; -typedef int (*grub_list_hook_t) (grub_list_t item); -typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); - void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); From 0959e5ec30d629f661129bbaf4dfed8c41c7a5d9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:20:52 +0100 Subject: [PATCH 106/503] Remove grub_list_pop --- gettext/gettext.c | 10 +++------- include/grub/list.h | 1 - kern/list.c | 12 ------------ normal/handler.c | 8 +++++--- tests/lib/test.c | 4 +++- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/gettext/gettext.c b/gettext/gettext.c index 0aa8decbd..bc7d42824 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -309,14 +309,10 @@ grub_gettext_init_ext (const char *lang) static void grub_gettext_delete_list (void) { - struct grub_gettext_msg *item; - - while ((item = - grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0) + while (grub_gettext_msg_list) { - char *original = (char *) ((struct grub_gettext_msg *) item)->name; - grub_free (original); - + grub_free ((char *) grub_gettext_msg_list->name); + grub_gettext_msg_list = grub_gettext_msg_list->next; /* Don't delete the translated message because could be in use. */ } } diff --git a/include/grub/list.h b/include/grub/list.h index d3abd69c4..75353010c 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -31,7 +31,6 @@ struct grub_list typedef struct grub_list *grub_list_t; void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); -void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) diff --git a/kern/list.c b/kern/list.c index 5b0248129..33c334166 100644 --- a/kern/list.c +++ b/kern/list.c @@ -28,18 +28,6 @@ grub_list_push (grub_list_t *head, grub_list_t item) *head = item; } -void * -grub_list_pop (grub_list_t *head) -{ - grub_list_t item; - - item = *head; - if (item) - *head = item->next; - - return item; -} - void grub_list_remove (grub_list_t *head, grub_list_t item) { diff --git a/normal/handler.c b/normal/handler.c index 8c97fd9a8..4c8b8f769 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -33,7 +33,7 @@ struct grub_handler_list grub_command_t cmd; }; -static grub_list_t handler_list; +static struct grub_handler_list *handler_list; static grub_err_t grub_handler_cmd (struct grub_command *cmd, @@ -127,7 +127,7 @@ insert_handler (char *name, char *module) } item->cmd->data = data; - grub_list_push (&handler_list, GRUB_AS_LIST (item)); + grub_list_push (GRUB_AS_LIST_P (&handler_list), GRUB_AS_LIST (item)); } /* Read the file handler.lst for auto-loading. */ @@ -211,8 +211,10 @@ free_handler_list (void) { struct grub_handler_list *item; - while ((item = grub_list_pop (&handler_list)) != 0) + while (handler_list) { + item = handler_list; + handler_list = handler_list->next; grub_free (item->cmd->data); grub_unregister_command (item->cmd); grub_free (item->name); diff --git a/tests/lib/test.c b/tests/lib/test.c index 3029495c6..06d78b7d7 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -66,8 +66,10 @@ free_failures (void) { grub_test_failure_t item; - while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0) + while (failure_list) { + item = failure_list; + failure_list = item->next; if (item->message) grub_free (item->message); From d56a6ac7f67fcfaf5490c0d3d9bb9240ac2c31f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:19:42 +0100 Subject: [PATCH 107/503] Remove handlers --- commands/handler.c | 103 ------------------ conf/any-emu.rmk | 2 +- conf/common.rmk | 43 ++------ conf/i386-coreboot.rmk | 2 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 4 +- conf/i386-qemu.rmk | 2 +- conf/mips-qemu-mips.rmk | 2 +- conf/mips-yeeloong.rmk | 2 +- conf/powerpc-ieee1275.rmk | 2 +- conf/sparc64-ieee1275.rmk | 2 +- conf/x86-efi.rmk | 2 +- include/grub/handler.h | 60 ---------- include/grub/parser.h | 32 +----- include/grub/script_sh.h | 3 + include/grub/term.h | 2 +- kern/handler.c | 64 ----------- kern/main.c | 1 - kern/parser.c | 8 +- kern/rescue_parser.c | 14 +-- kern/rescue_reader.c | 2 +- normal/handler.c | 223 -------------------------------------- normal/main.c | 53 ++------- normal/menu_entry.c | 3 +- script/main.c | 18 +-- util/grub-fstest.c | 3 - util/grub-probe.c | 3 - util/grub-script-check.c | 7 -- util/i386/pc/grub-setup.c | 3 - 29 files changed, 40 insertions(+), 627 deletions(-) delete mode 100644 commands/handler.c delete mode 100644 include/grub/handler.h delete mode 100644 kern/handler.c delete mode 100644 normal/handler.c diff --git a/commands/handler.c b/commands/handler.c deleted file mode 100644 index 2bfa67415..000000000 --- a/commands/handler.c +++ /dev/null @@ -1,103 +0,0 @@ -/* handler.c - commands to list or select handlers */ -/* - * 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 - -static grub_err_t -grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - void *curr_item = 0; - grub_handler_class_t head; - - head = grub_handler_class_list; - if (argc == 0) - { - grub_handler_class_t item; - FOR_LIST_ELEMENTS(item, head) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - } - } - else - { - char *class_name; - grub_handler_class_t class; - - class_name = args[0]; - argc--; - args++; - - class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name); - if (! class) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found"); - - if (argc == 0) - { - grub_handler_class_t item; - curr_item = class->cur_handler; - FOR_LIST_ELEMENTS(item, head) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - } - } - else - { - grub_handler_t handler; - - handler = - grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list), - args[0]); - - if (! handler) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found"); - - grub_handler_set_current (class, handler); - } - } - - return 0; -} - -static grub_command_t cmd_handler; - -GRUB_MOD_INIT(handler) -{ - cmd_handler = - grub_register_command ("handler", grub_cmd_handler, - N_("[class [handler]]"), - N_("List or select a handler.")); -} - -GRUB_MOD_FINI(handler) -{ - grub_unregister_command (cmd_handler); -} diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 758a8d720..3a2c47bf5 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -7,7 +7,7 @@ util/grub-emu.c_DEPENDENCIES = grub_emu_init.h kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ - kern/err.c kern/list.c kern/handler.c kern/command.c \ + kern/err.c kern/list.c kern/command.c \ kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ diff --git a/conf/common.rmk b/conf/common.rmk index f55bbfe0c..6300af3aa 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -27,7 +27,7 @@ util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c 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 kern/list.c \ + kern/partition.c kern/file.c kern/list.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 \ @@ -104,12 +104,11 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h # For grub-script-check. bin_UTILITIES += grub-script-check -util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ util/grub-script-check.c util/misc.c \ script/main.c script/script.c script/function.c script/lexer.c \ - kern/handler.c kern/err.c kern/parser.c kern/list.c \ - kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ + kern/err.c kern/list.c \ + kern/misc.c kern/env.c grub_script.tab.c \ grub_script.yy.c MOSTLYCLEANFILES += symlist.c kernel_syms.lst @@ -119,7 +118,7 @@ kernel_img_HEADERS += 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 msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/memory.h machine/loader.h machine/kernel.h \ - list.h handler.h command.h i18n.h env_private.h + list.h command.h i18n.h env_private.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) @@ -132,19 +131,6 @@ grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h -# For grub-script-check. -grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) - rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ -DISTCLEANFILES += grub_script_check_init.lst - -grub_script_check_init.h: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninitheader.sh - rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ -DISTCLEANFILES += grub_script_check_init.h - -grub_script_check_init.c: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninit.sh - rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ -DISTCLEANFILES += grub_script_check_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 > $@ @@ -455,12 +441,12 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS) scsi_mod_LDFLAGS = $(COMMON_LDFLAGS) # Commands. -pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \ +pkglib_MODULES += minicmd.mod extcmd.mod hello.mod \ ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \ configfile.mod echo.mod \ terminfo.mod test.mod blocklist.mod hexdump.mod \ read.mod sleep.mod loadenv.mod crc.mod parttool.mod \ - msdospart.mod memrw.mod normal.mod sh.mod \ + msdospart.mod memrw.mod normal.mod \ gptsync.mod true.mod probe.mod password.mod \ keystatus.mod @@ -521,11 +507,6 @@ msdospart_mod_SOURCES = parttool/msdospart.c msdospart_mod_CFLAGS = $(COMMON_CFLAGS) msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For handler.mod. -handler_mod_SOURCES = commands/handler.c -handler_mod_CFLAGS = $(COMMON_CFLAGS) -handler_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For ls.mod. ls_mod_SOURCES = commands/ls.c ls_mod_CFLAGS = $(COMMON_CFLAGS) @@ -645,19 +626,15 @@ keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS) # For normal.mod. normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ - normal/auth.c normal/autofs.c normal/handler.c \ + normal/auth.c normal/autofs.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c \ - normal/misc.c normal/crypto.c normal/term.c normal/context.c + normal/misc.c normal/crypto.c normal/term.c normal/context.c \ + script/main.c script/script.c script/execute.c \ + script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For sh.mod. -sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ - script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c -sh_mod_CFLAGS = $(COMMON_CFLAGS) -sh_mod_LDFLAGS = $(COMMON_LDFLAGS) - ifneq (, $(FONT_SOURCE)) font/font.c_DEPENDENCIES = ascii.h endif diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 3cef9313f..0979f03ee 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index d4a459b3e..f8921df9b 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -18,7 +18,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \ kern/rescue_parser.c kern/rescue_reader.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/env.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/generic/millisleep.c \ kern/ieee1275/ieee1275.c \ term/ieee1275/ofconsole.c \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index ece88446b..7b624837b 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -45,7 +45,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/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 \ @@ -76,7 +76,7 @@ util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ 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/err.c kern/misc.c kern/partition.c \ kern/file.c kern/fs.c kern/env.c kern/list.c \ fs/fshelp.c \ \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 97273e1ce..cbe6d0455 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -29,7 +29,7 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index e06370122..7cddf72ad 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -12,7 +12,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 35cd01b4b..bf39bf668 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -15,7 +15,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ kern/$(target_cpu)/cache.S \ diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 86f6ddcb3..7b32b24f1 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -13,7 +13,7 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/ieee1275/init.c \ kern/ieee1275/mmap.c \ term/ieee1275/ofconsole.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 78e511e31..b4079dd1f 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -25,7 +25,7 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/sparc64/ieee1275/ieee1275.c \ kern/sparc64/ieee1275/init.c \ kern/ieee1275/mmap.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 5cb472168..bab68f0f4 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -30,7 +30,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.c kern/$(target_cpu)/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/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c diff --git a/include/grub/handler.h b/include/grub/handler.h deleted file mode 100644 index 77dd7d9c1..000000000 --- a/include/grub/handler.h +++ /dev/null @@ -1,60 +0,0 @@ -/* handler.h - header for grub handler */ -/* - * 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_HANDLER_HEADER -#define GRUB_HANDLER_HEADER 1 - -#include -#include - -struct grub_handler -{ - struct grub_handler *next; - const char *name; - grub_err_t (*init) (void); - grub_err_t (*fini) (void); -}; -typedef struct grub_handler *grub_handler_t; - -struct grub_handler_class -{ - struct grub_handler_class *next; - const char *name; - grub_handler_t handler_list; - grub_handler_t cur_handler; -}; -typedef struct grub_handler_class *grub_handler_class_t; - -extern grub_handler_class_t EXPORT_VAR(grub_handler_class_list); - -void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class, - grub_handler_t handler); -void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class, - grub_handler_t handler); -grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class, - grub_handler_t handler); - -#define GRUB_AS_HANDLER(ptr) \ - ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \ - (grub_handler_t) ptr : grub_bad_type_cast ()) - -#endif /* ! GRUB_HANDLER_HEADER */ diff --git a/include/grub/parser.h b/include/grub/parser.h index 17f0c4303..064f73fcb 100644 --- a/include/grub/parser.h +++ b/include/grub/parser.h @@ -22,7 +22,6 @@ #include #include -#include #include /* All the states for the command line. */ @@ -84,36 +83,9 @@ struct grub_parser }; typedef struct grub_parser *grub_parser_t; -extern struct grub_handler_class EXPORT_VAR(grub_parser_class); grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source); -static inline void -grub_parser_register (const char *name __attribute__ ((unused)), - /* `name' is ignored here, but used by genhandlerlist.sh. */ - grub_parser_t parser) -{ - grub_handler_register (&grub_parser_class, GRUB_AS_HANDLER (parser)); -} - -static inline void -grub_parser_unregister (grub_parser_t parser) -{ - grub_handler_unregister (&grub_parser_class, GRUB_AS_HANDLER (parser)); -} - -static inline grub_parser_t -grub_parser_get_current (void) -{ - return (grub_parser_t) grub_parser_class.cur_handler; -} - -static inline grub_err_t -grub_parser_set_current (grub_parser_t parser) -{ - return grub_handler_set_current (&grub_parser_class, - GRUB_AS_HANDLER (parser)); -} - -void grub_register_rescue_parser (void); +grub_err_t +grub_rescue_parse_line (char *line, grub_reader_getline_t getline); #endif /* ! GRUB_PARSER_HEADER */ diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 33c6d2b85..5e85d983e 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -324,4 +324,7 @@ int grub_script_function_call (grub_script_function_t func, char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count); +grub_err_t +grub_normal_parse_line (char *line, grub_reader_getline_t getline); + #endif /* ! GRUB_NORMAL_PARSER_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h index 230436388..4a05909da 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include /* These are used to represent the various color states we use. */ typedef enum diff --git a/kern/handler.c b/kern/handler.c deleted file mode 100644 index 2bf85313c..000000000 --- a/kern/handler.c +++ /dev/null @@ -1,64 +0,0 @@ -/* handler.c - grub handler function */ -/* - * 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 - -grub_handler_class_t grub_handler_class_list; - -void -grub_handler_register (grub_handler_class_t class, grub_handler_t handler) -{ - int first_handler = (class->handler_list == 0); - - grub_list_push (GRUB_AS_LIST_P (&class->handler_list), - GRUB_AS_LIST (handler)); - - if (first_handler) - { - grub_list_push (GRUB_AS_LIST_P (&grub_handler_class_list), - GRUB_AS_LIST (class)); - grub_handler_set_current (class, handler); - } -} - -void -grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler) -{ - grub_list_remove (GRUB_AS_LIST_P (&class->handler_list), - GRUB_AS_LIST (handler)); - - if (class->handler_list == 0) - grub_list_remove (GRUB_AS_LIST_P (&grub_handler_class_list), - GRUB_AS_LIST (class)); -} - -grub_err_t -grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler) -{ - if (class->cur_handler && class->cur_handler->fini) - if ((class->cur_handler->fini) () != GRUB_ERR_NONE) - return grub_errno; - - if (handler->init) - if ((handler->init) () != GRUB_ERR_NONE) - return grub_errno; - - class->cur_handler = handler; - return GRUB_ERR_NONE; -} diff --git a/kern/main.c b/kern/main.c index 2f2c951ab..e644ea5b1 100644 --- a/kern/main.c +++ b/kern/main.c @@ -191,7 +191,6 @@ grub_main (void) grub_set_root_dev (); grub_register_core_commands (); - grub_register_rescue_parser (); grub_load_config (); grub_load_normal_mode (); diff --git a/kern/parser.c b/kern/parser.c index 80312b9b4..06e4ed673 100644 --- a/kern/parser.c +++ b/kern/parser.c @@ -230,10 +230,6 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, return 0; } -struct grub_handler_class grub_parser_class = { - .name = "parser" -}; - grub_err_t grub_parser_execute (char *source) { @@ -262,11 +258,9 @@ grub_parser_execute (char *source) while (source) { char *line; - grub_parser_t parser; getline (&line, 0); - parser = grub_parser_get_current (); - parser->parse_line (line, getline); + grub_rescue_parse_line (line, getline); grub_free (line); } diff --git a/kern/rescue_parser.c b/kern/rescue_parser.c index d3725e739..9c85ba6bd 100644 --- a/kern/rescue_parser.c +++ b/kern/rescue_parser.c @@ -24,7 +24,7 @@ #include #include -static grub_err_t +grub_err_t grub_rescue_parse_line (char *line, grub_reader_getline_t getline) { char *name; @@ -74,15 +74,3 @@ grub_rescue_parse_line (char *line, grub_reader_getline_t getline) return grub_errno; } - -static struct grub_parser grub_rescue_parser = - { - .name = "rescue", - .parse_line = grub_rescue_parse_line - }; - -void -grub_register_rescue_parser (void) -{ - grub_parser_register ("rescue", &grub_rescue_parser); -} diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c index f573cf41f..2f053aaea 100644 --- a/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -86,7 +86,7 @@ grub_rescue_run (void) if (! line || line[0] == '\0') continue; - grub_parser_get_current ()->parse_line (line, grub_rescue_read_line); + grub_rescue_parse_line (line, grub_rescue_read_line); grub_free (line); } } diff --git a/normal/handler.c b/normal/handler.c deleted file mode 100644 index 4c8b8f769..000000000 --- a/normal/handler.c +++ /dev/null @@ -1,223 +0,0 @@ -/* handler.c - support handler loading */ -/* - * 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 - -struct grub_handler_list -{ - struct grub_handler_list *next; - char *name; - grub_command_t cmd; -}; - -static struct grub_handler_list *handler_list; - -static grub_err_t -grub_handler_cmd (struct grub_command *cmd, - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - char *p; - grub_handler_class_t class; - grub_handler_t handler; - - p = grub_strchr (cmd->name, '.'); - if (! p) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name"); - - if (cmd->data) - { - if (! grub_dl_get (cmd->data)) - { - grub_dl_t mod; - - mod = grub_dl_load (cmd->data); - if (mod) - grub_dl_ref (mod); - else - return grub_errno; - } - grub_free (cmd->data); - cmd->data = 0; - } - - *p = 0; - class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list), - cmd->name); - *p = '.'; - - if (! class) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found"); - - - handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list), - p + 1); - if (! handler) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found"); - - grub_handler_set_current (class, handler); - - return 0; -} - -static void -insert_handler (char *name, char *module) -{ - struct grub_handler_list *item; - char *data; - - if (grub_command_find (name)) - return; - - item = grub_malloc (sizeof (*item)); - if (! item) - return; - - item->name = grub_strdup (name); - if (! item->name) - { - grub_free (item); - return; - } - - if (module) - { - data = grub_strdup (module); - if (! data) - { - grub_free (item->name); - grub_free (item); - return; - } - } - else - data = 0; - - item->cmd = grub_register_command (item->name, grub_handler_cmd, 0, - "Set active handler."); - if (! item->cmd) - { - grub_free (data); - grub_free (item->name); - grub_free (item); - return; - } - - item->cmd->data = data; - grub_list_push (GRUB_AS_LIST_P (&handler_list), GRUB_AS_LIST (item)); -} - -/* Read the file handler.lst for auto-loading. */ -void -read_handler_list (void) -{ - const char *prefix; - static int first_time = 1; - const char *class_name; - - /* Make sure that this function does not get executed twice. */ - if (! first_time) - return; - first_time = 0; - - prefix = grub_env_get ("prefix"); - if (prefix) - { - char *filename; - - filename = grub_xasprintf ("%s/handler.lst", prefix); - if (filename) - { - grub_file_t file; - - file = grub_file_open (filename); - if (file) - { - char *buf = NULL; - for (;; grub_free (buf)) - { - char *p; - - buf = grub_file_getline (file); - - if (! buf) - break; - - if (! grub_isgraph (buf[0])) - continue; - - p = grub_strchr (buf, ':'); - if (! p) - continue; - - *p = '\0'; - while (*++p == ' ') - ; - - insert_handler (buf, p); - } - grub_file_close (file); - } - grub_free (filename); - } - } - - grub_handler_class_t class; - FOR_LIST_ELEMENTS (class, grub_handler_class_list) - { - grub_handler_t handler; - class_name = class->name; - FOR_LIST_ELEMENTS(handler, class->handler_list) - { - char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; - - grub_strcpy (name, class_name); - grub_strcat (name, "."); - grub_strcat (name, handler->name); - - insert_handler (name, 0); - } - } - - /* Ignore errors. */ - grub_errno = GRUB_ERR_NONE; -} - -void -free_handler_list (void) -{ - struct grub_handler_list *item; - - while (handler_list) - { - item = handler_list; - handler_list = handler_list->next; - grub_free (item->cmd->data); - grub_unregister_command (item->cmd); - grub_free (item->name); - grub_free (item); - } -} diff --git a/normal/main.c b/normal/main.c index 5a5467485..e16e8ef7d 100644 --- a/normal/main.c +++ b/normal/main.c @@ -31,6 +31,7 @@ #include #include #include +#include #define GRUB_DEFAULT_HISTORY_SIZE 50 @@ -308,7 +309,6 @@ static grub_menu_t read_config_file (const char *config) { grub_file_t file; - grub_parser_t old_parser = 0; auto grub_err_t getline (char **line, int cont); grub_err_t getline (char **line, int cont __attribute__ ((unused))) @@ -322,36 +322,7 @@ read_config_file (const char *config) return grub_errno; if (buf[0] == '#') - { - if (buf[1] == '!') - { - grub_parser_t parser; - grub_named_list_t list; - - buf += 2; - while (grub_isspace (*buf)) - buf++; - - if (! old_parser) - old_parser = grub_parser_get_current (); - - list = GRUB_AS_NAMED_LIST (grub_parser_class.handler_list); - parser = grub_named_list_find (list, buf); - if (parser) - grub_parser_set_current (parser); - else - { - char cmd_name[8 + grub_strlen (buf)]; - - /* Perhaps it's not loaded yet, try the autoload - command. */ - grub_strcpy (cmd_name, "parser."); - grub_strcat (cmd_name, buf); - grub_command_execute (cmd_name, 0, 0); - } - } - grub_free (*line); - } + grub_free (*line); else break; } @@ -387,15 +358,12 @@ read_config_file (const char *config) if ((getline (&line, 0)) || (! line)) break; - grub_parser_get_current ()->parse_line (line, getline); + grub_normal_parse_line (line, getline); grub_free (line); } grub_file_close (file); - if (old_parser) - grub_parser_set_current (old_parser); - return newmenu; } @@ -453,7 +421,6 @@ grub_normal_execute (const char *config, int nested, int batch) grub_menu_t menu = 0; read_lists (NULL, NULL); - read_handler_list (); grub_register_variable_hook ("prefix", NULL, read_lists); grub_command_execute ("parser.grub", 0, 0); @@ -559,17 +526,15 @@ grub_normal_reader_init (int nested) return 0; } - static grub_err_t grub_normal_read_line_real (char **line, int cont, int nested) { - grub_parser_t parser = grub_parser_get_current (); - char *prompt; + const char *prompt; if (cont) - prompt = grub_xasprintf (">"); + prompt = ">"; else - prompt = grub_xasprintf ("%s>", parser->name); + prompt = "grub>"; if (!prompt) return grub_errno; @@ -583,14 +548,11 @@ grub_normal_read_line_real (char **line, int cont, int nested) if (cont || nested) { grub_free (*line); - grub_free (prompt); *line = 0; return grub_errno; } } - grub_free (prompt); - return 0; } @@ -631,7 +593,7 @@ grub_cmdline_run (int nested) if (! line) break; - grub_parser_get_current ()->parse_line (line, grub_normal_read_line); + grub_normal_parse_line (line, grub_normal_read_line); grub_free (line); } } @@ -679,5 +641,4 @@ GRUB_MOD_FINI(normal) grub_set_history (0); grub_register_variable_hook ("pager", 0, 0); grub_fs_autoload_hook = 0; - free_handler_list (); } diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 644fe90fd..c23d67d70 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1189,7 +1190,7 @@ run (struct screen *screen) while (currline < screen->num_lines) { editor_getline (&nextline, 0); - if (grub_parser_get_current ()->parse_line (nextline, editor_getline)) + if (grub_normal_parse_line (nextline, editor_getline)) break; } diff --git a/script/main.c b/script/main.c index b5159dc7d..752a8cd8a 100644 --- a/script/main.c +++ b/script/main.c @@ -20,7 +20,7 @@ #include #include -static grub_err_t +grub_err_t grub_normal_parse_line (char *line, grub_reader_getline_t getline) { struct grub_script *parsed_script; @@ -39,19 +39,3 @@ grub_normal_parse_line (char *line, grub_reader_getline_t getline) return grub_errno; } - -static struct grub_parser grub_sh_parser = - { - .name = "grub", - .parse_line = grub_normal_parse_line - }; - -GRUB_MOD_INIT(sh) -{ - grub_parser_register ("grub", &grub_sh_parser); -} - -GRUB_MOD_FINI(sh) -{ - grub_parser_unregister (&grub_sh_parser); -} diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c03c43451..f7e1eb2dd 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -55,9 +55,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { diff --git a/util/grub-probe.c b/util/grub-probe.c index 948f10dcf..37b92454a 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -70,9 +70,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 7dc400dde..722736c81 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -26,8 +26,6 @@ #include #include -#include - #define _GNU_SOURCE 1 #include @@ -232,9 +230,6 @@ main (int argc, char *argv[]) } } - /* Initialize all modules. */ - grub_init_all (); - do { input = 0; @@ -252,8 +247,6 @@ main (int argc, char *argv[]) grub_free (input); } while (script != 0); - /* Free resources. */ - grub_fini_all (); if (file) fclose (file); return (script == 0); diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..989b06360 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -69,9 +69,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { From c96db58ec599d1bcfb12bf345fb4988e1ef1a741 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:27:42 +0100 Subject: [PATCH 108/503] Remove grub_fs_iterate --- include/grub/fs.h | 26 ++++++++++++++++++++------ kern/fs.c | 32 +------------------------------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/include/grub/fs.h b/include/grub/fs.h index 45f515768..3368eb553 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -24,6 +24,8 @@ #include #include +#include + /* Forward declaration is required, because of mutual reference. */ struct grub_file; @@ -38,6 +40,9 @@ struct grub_dirhook_info /* Filesystem descriptor. */ struct grub_fs { + /* The next filesystem. */ + struct grub_fs *next; + /* My name. */ const char *name; @@ -72,9 +77,6 @@ struct grub_fs /* Whether this filesystem reserves first sector for DOS-style boot. */ int reserved_first_sector; #endif - - /* The next filesystem. */ - struct grub_fs *next; }; typedef struct grub_fs *grub_fs_t; @@ -87,10 +89,22 @@ extern struct grub_fs grub_fs_blocklist; 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); +extern grub_fs_t EXPORT_VAR (grub_fs_list); + +static inline void +grub_fs_register (grub_fs_t fs) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); +} + +static inline void +grub_fs_unregister (grub_fs_t fs) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); +} + +#define FOR_FILESYSTEMS(var) FOR_LIST_ELEMENTS((var), (grub_fs_list)) -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/kern/fs.c b/kern/fs.c index 0c456377f..cf800f4cc 100644 --- a/kern/fs.c +++ b/kern/fs.c @@ -27,40 +27,10 @@ #include #include -static grub_fs_t grub_fs_list; +grub_fs_t grub_fs_list = 0; 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) { From 9eade9dbd7602d4b9dbae8a09dc89a1631ab314e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:36:28 +0100 Subject: [PATCH 109/503] Remove grub_video_iterate --- include/grub/video.h | 29 +++++++++++++++++++++++------ video/video.c | 35 +---------------------------------- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/include/grub/video.h b/include/grub/video.h index 57f2b37f2..3e8ea0e96 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -21,6 +21,7 @@ #include #include +#include /* Video color in hardware dependent format. Users should not assume any specific coding format. */ @@ -185,6 +186,9 @@ typedef enum grub_video_driver_id struct grub_video_adapter { + /* The next video adapter. */ + struct grub_video_adapter *next; + /* The video adapter name. */ const char *name; grub_video_driver_id_t id; @@ -253,15 +257,28 @@ struct grub_video_adapter 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 EXPORT_FUNC (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)); +extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list); + +/* Register video driver. */ +static inline void +grub_video_register (grub_video_adapter_t adapter) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_video_adapter_list), + GRUB_AS_LIST (adapter)); +} + +/* Unregister video driver. */ +static inline void +grub_video_unregister (grub_video_adapter_t adapter) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_video_adapter_list), + GRUB_AS_LIST (adapter)); +} + +#define FOR_VIDEO_ADAPTERS(var) FOR_LIST_ELEMENTS((var), (grub_video_adapter_list)) grub_err_t EXPORT_FUNC (grub_video_restore) (void); diff --git a/video/video.c b/video/video.c index 42418f980..7a1a446e4 100644 --- a/video/video.c +++ b/video/video.c @@ -23,44 +23,11 @@ #include /* The list of video adapters registered to system. */ -static grub_video_adapter_t grub_video_adapter_list; +grub_video_adapter_t grub_video_adapter_list = NULL; /* 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; -} - /* Restore back to initial mode (where applicable). */ grub_err_t grub_video_restore (void) From fcaae9ec1242c54e0bd763d80f8427e70e9f7fde Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:52:40 +0100 Subject: [PATCH 110/503] Remove grub_dl_iterate --- commands/minicmd.c | 34 ++++++++++++++------------------ include/grub/dl.h | 6 +++++- kern/dl.c | 49 ++++++++++++---------------------------------- 3 files changed, 32 insertions(+), 57 deletions(-) diff --git a/commands/minicmd.c b/commands/minicmd.c index 4ea9efead..92d262caf 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -301,27 +301,23 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), 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'); - - return 0; - } + grub_dl_t mod; grub_printf ("Name\tRef Count\tDependencies\n"); - grub_dl_iterate (print_module); + FOR_DL_MODULES (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'); + } return 0; } diff --git a/include/grub/dl.h b/include/grub/dl.h index 17e03f400..c44e85aef 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -82,6 +82,7 @@ struct grub_dl Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); + struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -113,7 +114,10 @@ grub_dl_unref (grub_dl_t mod) int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); #endif -void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod)); +extern grub_dl_t EXPORT_VAR(grub_dl_head); + +#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head)) + grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); grub_err_t grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod); diff --git a/kern/dl.c b/kern/dl.c index 19ee13243..cf59cec30 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -39,31 +39,17 @@ -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; +grub_dl_t grub_dl_head = 0; 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; + mod->next = grub_dl_head; + grub_dl_head = mod; return GRUB_ERR_NONE; } @@ -71,13 +57,12 @@ grub_dl_add (grub_dl_t mod) static void grub_dl_remove (grub_dl_t mod) { - grub_dl_list_t *p, q; + grub_dl_t *p, q; for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p) - if (q->mod == mod) + if (q == mod) { *p = q->next; - grub_free (q); return; } } @@ -85,25 +70,15 @@ grub_dl_remove (grub_dl_t mod) grub_dl_t grub_dl_get (const char *name) { - grub_dl_list_t l; + grub_dl_t l; for (l = grub_dl_head; l; l = l->next) - if (grub_strcmp (name, l->mod->name) == 0) - return l->mod; + if (grub_strcmp (name, l->name) == 0) + return l; 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 @@ -690,11 +665,11 @@ 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; + grub_dl_t p = grub_dl_head; while (p) { - if (grub_dl_unload (p->mod)) + if (grub_dl_unload (p)) { p = grub_dl_head; continue; @@ -710,13 +685,13 @@ grub_dl_unload_all (void) { while (grub_dl_head) { - grub_dl_list_t p; + grub_dl_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--; + p->ref_count--; } } From 9cc7b8751eb717834864fc587412a4dbafa7066d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:58:35 +0100 Subject: [PATCH 111/503] Remove grub_script_function_iterate --- include/grub/script_sh.h | 6 +++++- script/function.c | 14 +------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 5e85d983e..020cbb2f7 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -313,11 +313,15 @@ struct grub_script_function }; typedef struct grub_script_function *grub_script_function_t; +extern grub_script_function_t grub_script_function_list; + +#define FOR_SCRIPT_FUNCTIONS(var) for((var) = grub_script_function_list; \ + (var); (var) = (var)->next) + grub_script_function_t grub_script_function_create (struct grub_script_arg *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); diff --git a/script/function.c b/script/function.c index ded470c4e..810c65233 100644 --- a/script/function.c +++ b/script/function.c @@ -21,7 +21,7 @@ #include #include -static grub_script_function_t grub_script_function_list; +grub_script_function_t grub_script_function_list; grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname_arg, @@ -104,18 +104,6 @@ grub_script_function_find (char *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)), From c0420b76b0885a9db8fb3911e9744ab5b58d92a6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 02:05:38 +0200 Subject: [PATCH 112/503] Fix ascii fallback --- font/font.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/font/font.c b/font/font.c index f39bd9e7e..d512ec98f 100644 --- a/font/font.c +++ b/font/font.c @@ -154,7 +154,7 @@ ascii_glyph_lookup (grub_uint32_t code) ascii_font_glyph[current]->font = NULL; grub_memcpy (ascii_font_glyph[current]->bitmap, - &ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE], + &ascii_bitmaps[current * ASCII_BITMAP_SIZE], ASCII_BITMAP_SIZE); } From 3f11c7131efb94091c89f43e16399b0d32315d38 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 02:06:40 +0200 Subject: [PATCH 113/503] Generate shaping table based on unicode if source font has none --- conf/common.rmk | 2 +- include/grub/unicode.h | 15 +++++++++ util/grub-mkfont.c | 73 +++++++++++++++++++++++++++++++++++++++--- util/import_unicode.py | 60 ++++++++++++++++++++++++++++------ 4 files changed, 135 insertions(+), 15 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index d790abade..c157e9578 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -82,7 +82,7 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ # For grub-mkfont. ifeq ($(enable_grub_mkfont), yes) bin_UTILITIES += grub-mkfont -grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c +grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c unidata.c grub_mkfont_CFLAGS = $(freetype_cflags) grub_mkfont_LDFLAGS = $(freetype_libs) endif diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 28c752b9e..9fde69cc8 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -39,6 +39,19 @@ struct grub_unicode_compact_range grub_uint8_t join_type:3; } __attribute__ ((packed)); +/* Old-style Arabic shaping. Used for "visual UTF-8" and + in grub-mkfont to find variant glyphs in absence of GPOS tables. */ +struct grub_unicode_arabic_shape +{ + grub_uint32_t code; + grub_uint32_t isolated; + grub_uint32_t right_linked; + grub_uint32_t both_linked; + grub_uint32_t left_linked; +}; + +extern struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[]; + enum grub_bidi_type { GRUB_BIDI_TYPE_L = 0, @@ -150,6 +163,8 @@ struct grub_unicode_glyph #define GRUB_UNICODE_HEBREW_WAW 0x05d5 #define GRUB_UNICODE_ZWNJ 0x200c #define GRUB_UNICODE_ZWJ 0x200d +#define GRUB_UNICODE_ARABIC_START 0x600 +#define GRUB_UNICODE_ARABIC_END 0x700 extern struct grub_unicode_compact_range grub_unicode_compact[]; extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index c9d48ed7a..886fc8d4a 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -184,12 +185,18 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, err = FT_Load_Glyph (face, glyph_idx, flag); if (err) { - if (err < ARRAY_SIZE (ft_errmsgs)) - printf ("Freetype Error %d loading glyph 0x%x for U+0x%x: %s\n", - err, glyph_idx, char_code, ft_errmsgs[err]); + printf ("Freetype Error %d loading glyph 0x%x for U+0x%x%s", + err, glyph_idx, char_code & GRUB_FONT_CODE_CHAR_MASK, + char_code & GRUB_FONT_CODE_RIGHT_JOINED + ? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (medial)": + " (leftmost)") + : ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (rightmost)": + "")); + + if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) + printf (": %s\n", ft_errmsgs[err]); else - printf ("Freetype Error %d loading glyph 0x%x for U+0x%x\n", - err, glyph_idx, char_code); + printf ("\n"); return; } @@ -268,6 +275,25 @@ add_char (struct grub_font_info *font_info, FT_Face face, char_code | GRUB_FONT_CODE_RIGHT_JOINED); break; } + if (!cur && char_code >= GRUB_UNICODE_ARABIC_START + && char_code < GRUB_UNICODE_ARABIC_END) + { + int i; + for (i = 0; grub_unicode_arabic_shapes[i].code; i++) + if (grub_unicode_arabic_shapes[i].code == char_code + && grub_unicode_arabic_shapes[i].right_linked) + { + FT_UInt idx2; + idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i] + .right_linked); + if (idx2) + add_glyph (font_info, idx2, face, + char_code | GRUB_FONT_CODE_RIGHT_JOINED); + break; + } + + } + for (cur = subst_leftjoin; cur; cur = cur->next) if (cur->from == glyph_idx) { @@ -275,6 +301,24 @@ add_char (struct grub_font_info *font_info, FT_Face face, char_code | GRUB_FONT_CODE_LEFT_JOINED); break; } + if (!cur && char_code >= GRUB_UNICODE_ARABIC_START + && char_code < GRUB_UNICODE_ARABIC_END) + { + int i; + for (i = 0; grub_unicode_arabic_shapes[i].code; i++) + if (grub_unicode_arabic_shapes[i].code == char_code + && grub_unicode_arabic_shapes[i].left_linked) + { + FT_UInt idx2; + idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i] + .left_linked); + if (idx2) + add_glyph (font_info, idx2, face, + char_code | GRUB_FONT_CODE_LEFT_JOINED); + break; + } + + } for (cur = subst_medijoin; cur; cur = cur->next) if (cur->from == glyph_idx) { @@ -283,6 +327,25 @@ add_char (struct grub_font_info *font_info, FT_Face face, | GRUB_FONT_CODE_RIGHT_JOINED); break; } + if (!cur && char_code >= GRUB_UNICODE_ARABIC_START + && char_code < GRUB_UNICODE_ARABIC_END) + { + int i; + for (i = 0; grub_unicode_arabic_shapes[i].code; i++) + if (grub_unicode_arabic_shapes[i].code == char_code + && grub_unicode_arabic_shapes[i].both_linked) + { + FT_UInt idx2; + idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i] + .both_linked); + if (idx2) + add_glyph (font_info, idx2, face, + char_code | GRUB_FONT_CODE_LEFT_JOINED + | GRUB_FONT_CODE_RIGHT_JOINED); + break; + } + + } } struct gsub_header diff --git a/util/import_unicode.py b/util/import_unicode.py index 653d7bae2..1ee162d3f 100644 --- a/util/import_unicode.py +++ b/util/import_unicode.py @@ -35,15 +35,15 @@ for line in infile: sp = line.split (";") curcode = int (sp[0], 16) if sp[2] == "U": - joining[curcode] = "GRUB_JOIN_TYPE_NONJOINING" + joining[curcode] = "NONJOINING" elif sp[2] == "L": - joining[curcode] = "GRUB_JOIN_TYPE_LEFT" + joining[curcode] = "LEFT" elif sp[2] == "R": - joining[curcode] = "GRUB_JOIN_TYPE_RIGHT" + joining[curcode] = "RIGHT" elif sp[2] == "D": - joining[curcode] = "GRUB_JOIN_TYPE_DUAL" + joining[curcode] = "DUAL" elif sp[2] == "C": - joining[curcode] = "GRUB_JOIN_TYPE_CAUSING" + joining[curcode] = "CAUSING" else: print ("Unknown joining type '%s'" % sp[2]) exit (1) @@ -60,6 +60,7 @@ lastcode = -2 lastbiditype = "X" lastmirrortype = False lastcombtype = -1 +arabicsubst = {} for line in infile: sp = line.split (";") curcode = int (sp[0], 16) @@ -102,15 +103,35 @@ for line in infile: if curcode in joining: curjoin = joining[curcode] elif sp[2] == "Me" or sp[2] == "Mn" or sp[2] == "Cf": - curjoin = "GRUB_JOIN_TYPE_TRANSPARENT" + curjoin = "TRANSPARENT" else: - curjoin = "GRUB_JOIN_TYPE_NONJOINING" + curjoin = "NONJOINING" + if sp[1].startswith ("ARABIC LETTER "): + arabname = sp[1][len ("ARABIC LETTER "):] + form = 0 + if arabname.endswith (" ISOLATED FORM"): + arabname = arabname[0:len (arabname) - len (" ISOLATED FORM")] + form = 1 + if arabname.endswith (" FINAL FORM"): + arabname = arabname[0:len (arabname) - len (" FINAL FORM")] + form = 2 + if arabname.endswith (" MEDIAL FORM"): + arabname = arabname[0:len (arabname) - len (" MEDIAL FORM")] + form = 3 + if arabname.endswith (" INITIAL FORM"): + arabname = arabname[0:len (arabname) - len (" INITIAL FORM")] + form = 4 + if arabname not in arabicsubst: + arabicsubst[arabname]={} + arabicsubst[arabname][form] = curcode; + if form == 0: + arabicsubst[arabname]['join'] = curjoin if lastcode + 1 != curcode or curbiditype != lastbiditype \ or curcombtype != lastcombtype or curmirrortype != lastmirrortype \ or curjoin != lastjoin: if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0 or \ lastmirrortype): - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, %s},\n" \ + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \ % (begincode, lastcode, lastbiditype, \ lastcombtype, lastmirrortype, \ lastjoin))) @@ -121,7 +142,7 @@ for line in infile: lastcombtype = curcombtype lastmirrortype = curmirrortype if lastbiditype != "L" or lastcombtype != 0 or lastmirrortype: - outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, %s},\n" \ + outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \ % (begincode, lastcode, lastbiditype, lastcombtype, \ lastmirrortype, lastjoin))) outfile.write ("{0, 0, 0, 0, 0, 0},\n") @@ -147,3 +168,24 @@ for line in infile: outfile.write ("{0, 0},\n") outfile.write ("};\n") +infile.close () + +outfile.write ("struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[] = {\n ") + +for x in arabicsubst: + try: + if arabicsubst[x]['join'] == "DUAL": + outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], arabicsubst[x][3], arabicsubst[x][4])) + elif arabicsubst[x]['join'] == "RIGHT": + outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], 0, 0)) + elif arabicsubst[x]['join'] == "LEFT": + outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], 0, 0, arabicsubst[x][4])) + except: + pass + +outfile.write ("{0, 0, 0, 0, 0},\n") +outfile.write ("};\n") + + +outfile.close () + From a6ab5fb2cf541b93a4e1a2fd1c0c58a8ccd13133 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 03:13:59 +0200 Subject: [PATCH 114/503] Cut font borders --- util/grub-mkfont.c | 89 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 19 deletions(-) diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 886fc8d4a..970cc4aca 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -164,10 +164,11 @@ add_pixel (grub_uint8_t **data, int *mask, int not_blank) static void add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - grub_uint32_t char_code) + grub_uint32_t char_code, int nocut) { struct grub_glyph_info *glyph_info; int width, height; + int cuttop, cutbottom, cutleft, cutright; grub_uint8_t *data; int mask, i, j, bitmap_size; FT_GlyphSlot glyph; @@ -208,8 +209,58 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, if (glyph->next) printf ("%x\n", char_code); - width = glyph->bitmap.width; - height = glyph->bitmap.rows; + if (nocut) + cuttop = cutbottom = cutleft = cutright = 0; + else + { + for (cuttop = 0; cuttop < glyph->bitmap.rows; cuttop++) + { + for (j = 0; j < glyph->bitmap.width; j++) + if (glyph->bitmap.buffer[j / 8 + cuttop * glyph->bitmap.pitch] + & (1 << (7 - (j & 7)))) + break; + if (j != glyph->bitmap.width) + break; + } + + for (cutbottom = glyph->bitmap.rows - 1; cutbottom >= 0; cutbottom--) + { + for (j = 0; j < glyph->bitmap.width; j++) + if (glyph->bitmap.buffer[j / 8 + cutbottom * glyph->bitmap.pitch] + & (1 << (7 - (j & 7)))) + break; + if (j != glyph->bitmap.width) + break; + } + cutbottom = glyph->bitmap.rows - 1 - cutbottom; + if (cutbottom + cuttop >= glyph->bitmap.rows) + cutbottom = 0; + + for (cutleft = 0; cutleft < glyph->bitmap.width; cutleft++) + { + for (j = 0; j < glyph->bitmap.rows; j++) + if (glyph->bitmap.buffer[cutleft / 8 + j * glyph->bitmap.pitch] + & (1 << (7 - (cutleft & 7)))) + break; + if (j != glyph->bitmap.rows) + break; + } + for (cutright = glyph->bitmap.width - 1; cutright >= 0; cutright--) + { + for (j = 0; j < glyph->bitmap.rows; j++) + if (glyph->bitmap.buffer[cutright / 8 + j * glyph->bitmap.pitch] + & (1 << (7 - (cutright & 7)))) + break; + if (j != glyph->bitmap.rows) + break; + } + cutright = glyph->bitmap.width - 1 - cutright; + if (cutright + cutleft >= glyph->bitmap.width) + cutright = 0; + } + + width = glyph->bitmap.width - cutleft - cutright; + height = glyph->bitmap.rows - cutbottom - cuttop; bitmap_size = ((width * height + 7) / 8); glyph_info = xmalloc (sizeof (struct grub_glyph_info)); @@ -223,8 +274,8 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, 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->x_ofs = glyph->bitmap_left + cutleft; + glyph_info->y_ofs = glyph->bitmap_top - height - cuttop; glyph_info->device_width = glyph->metrics.horiAdvance / 64; if (width > font_info->max_width) @@ -241,8 +292,8 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, mask = 0; data = &glyph_info->bitmap[0] - 1; - for (j = 0; j < height; j++) - for (i = 0; i < width; i++) + for (j = cuttop; j < height + cuttop; j++) + for (i = cutleft; i < width + cutleft; i++) add_pixel (&data, &mask, glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] & (1 << (7 - (i & 7)))); @@ -259,7 +310,7 @@ struct glyph_replace /* TODO: sort glyph_replace and use binary search if necessary. */ static void add_char (struct grub_font_info *font_info, FT_Face face, - grub_uint32_t char_code) + grub_uint32_t char_code, int nocut) { FT_UInt glyph_idx; struct glyph_replace *cur; @@ -267,12 +318,12 @@ add_char (struct grub_font_info *font_info, FT_Face face, glyph_idx = FT_Get_Char_Index (face, char_code); if (!glyph_idx) return; - add_glyph (font_info, glyph_idx, face, char_code); + add_glyph (font_info, glyph_idx, face, char_code, nocut); for (cur = subst_rightjoin; cur; cur = cur->next) if (cur->from == glyph_idx) { add_glyph (font_info, cur->to, face, - char_code | GRUB_FONT_CODE_RIGHT_JOINED); + char_code | GRUB_FONT_CODE_RIGHT_JOINED, nocut); break; } if (!cur && char_code >= GRUB_UNICODE_ARABIC_START @@ -288,7 +339,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, .right_linked); if (idx2) add_glyph (font_info, idx2, face, - char_code | GRUB_FONT_CODE_RIGHT_JOINED); + char_code | GRUB_FONT_CODE_RIGHT_JOINED, nocut); break; } @@ -298,7 +349,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, if (cur->from == glyph_idx) { add_glyph (font_info, cur->to, face, - char_code | GRUB_FONT_CODE_LEFT_JOINED); + char_code | GRUB_FONT_CODE_LEFT_JOINED, nocut); break; } if (!cur && char_code >= GRUB_UNICODE_ARABIC_START @@ -314,7 +365,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, .left_linked); if (idx2) add_glyph (font_info, idx2, face, - char_code | GRUB_FONT_CODE_LEFT_JOINED); + char_code | GRUB_FONT_CODE_LEFT_JOINED, nocut); break; } @@ -324,7 +375,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, { add_glyph (font_info, cur->to, face, char_code | GRUB_FONT_CODE_LEFT_JOINED - | GRUB_FONT_CODE_RIGHT_JOINED); + | GRUB_FONT_CODE_RIGHT_JOINED, nocut); break; } if (!cur && char_code >= GRUB_UNICODE_ARABIC_START @@ -341,7 +392,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, if (idx2) add_glyph (font_info, idx2, face, char_code | GRUB_FONT_CODE_LEFT_JOINED - | GRUB_FONT_CODE_RIGHT_JOINED); + | GRUB_FONT_CODE_RIGHT_JOINED, nocut); break; } @@ -554,7 +605,7 @@ process_cursive (struct gsub_feature *feature, } void -add_font (struct grub_font_info *font_info, FT_Face face) +add_font (struct grub_font_info *font_info, FT_Face face, int nocut) { struct gsub_header *gsub = NULL; FT_ULong gsub_len = 0; @@ -631,7 +682,7 @@ add_font (struct grub_font_info *font_info, FT_Face face) 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); + add_char (font_info, face, j, nocut); } else { @@ -640,7 +691,7 @@ add_font (struct grub_font_info *font_info, FT_Face face) 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); + add_char (font_info, face, char_code, nocut); } } @@ -1118,7 +1169,7 @@ main (int argc, char *argv[]) font_info.size = size; FT_Set_Pixel_Sizes (ft_face, size, size); - add_font (&font_info, ft_face); + add_font (&font_info, ft_face, file_format != PF2); FT_Done_Face (ft_face); } From a82890fffcb113f48fee854e5fc38aca9ec39158 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 03:37:24 +0200 Subject: [PATCH 115/503] Shape arabic code when on UTF-8 visual --- include/grub/unicode.h | 2 ++ normal/charset.c | 36 ++++++++++++++++++++++++++++++++++++ normal/term.c | 9 ++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 9fde69cc8..a779e2c9c 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -222,5 +222,7 @@ grub_unicode_glyph_from_code (grub_uint32_t code) grub_uint32_t grub_unicode_mirror_code (grub_uint32_t in); +grub_uint32_t +grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr); #endif diff --git a/normal/charset.c b/normal/charset.c index 55a9894a9..6f09fac90 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1227,3 +1227,39 @@ grub_unicode_mirror_code (grub_uint32_t in) return grub_unicode_bidi_pairs[i].replace; return in; } + +grub_uint32_t +grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr) +{ + int i; + if (!(in >= GRUB_UNICODE_ARABIC_START + && in < GRUB_UNICODE_ARABIC_END)) + return in; + + for (i = 0; grub_unicode_arabic_shapes[i].code; i++) + if (grub_unicode_arabic_shapes[i].code == in) + { + grub_uint32_t out; + switch (attr & (GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED + | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)) + { + case 0: + out = grub_unicode_arabic_shapes[i].isolated; + break; + case GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED: + out = grub_unicode_arabic_shapes[i].right_linked; + break; + case GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED: + out = grub_unicode_arabic_shapes[i].left_linked; + break; + case GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED + |GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED: + out = grub_unicode_arabic_shapes[i].both_linked; + break; + } + if (out) + return out; + } + + return in; +} diff --git a/normal/term.c b/normal/term.c index 09299f647..4724c5d41 100644 --- a/normal/term.c +++ b/normal/term.c @@ -392,9 +392,12 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) { code = c->base; if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL - && (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)) - code = grub_unicode_mirror_code (code); + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) + { + if ((c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)) + code = grub_unicode_mirror_code (code); + code = grub_unicode_shape_code (code, c->attributes); + } } else code = c->combining[i].code; From ad109fe05639d21fe8fb3c317f12f6fd75d2e058 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 04:11:14 +0200 Subject: [PATCH 116/503] Arabic diacritics support --- font/font.c | 12 +++++++++++- include/grub/unicode.h | 8 ++++++++ normal/charset.c | 25 ++++++++++++++++++++----- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/font/font.c b/font/font.c index d512ec98f..3aa415cdc 100644 --- a/font/font.c +++ b/font/font.c @@ -1248,6 +1248,13 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, min_devwidth = combining_glyphs[i]->width; break; + /* TODO: Put dammah and fathah nearer to shadda. */ + case GRUB_UNICODE_COMB_ARABIC_DAMMAH: + case GRUB_UNICODE_COMB_ARABIC_DAMMATAN: + case GRUB_UNICODE_COMB_ARABIC_FATHATAN: + case GRUB_UNICODE_COMB_ARABIC_FATHAH: + case GRUB_UNICODE_COMB_ARABIC_SUKUN: + case GRUB_UNICODE_COMB_ARABIC_SHADDA: case GRUB_UNICODE_COMB_HEBREW_RAFE: case GRUB_UNICODE_STACK_ABOVE: space = combining_glyphs[i]->offset_y @@ -1276,12 +1283,15 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, case GRUB_UNICODE_COMB_HEBREW_PATAH: case GRUB_UNICODE_COMB_HEBREW_QUBUTS: case GRUB_UNICODE_COMB_HEBREW_METEG: + /* TODO: Put kasra and kasratan under shadda. */ + case GRUB_UNICODE_COMB_ARABIC_KASRA: + case GRUB_UNICODE_COMB_ARABIC_KASRATAN: /* I don't know how ypogegrammeni differs from subscript. */ case GRUB_UNICODE_COMB_YPOGEGRAMMENI: case GRUB_UNICODE_STACK_BELOW: space = -(combining_glyphs[i]->offset_y + combining_glyphs[i]->height); - if (space < 0) + if (space <= 0) space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; case GRUB_UNICODE_STACK_ATTACHED_BELOW: diff --git a/include/grub/unicode.h b/include/grub/unicode.h index a779e2c9c..19837d82e 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -106,6 +106,14 @@ enum grub_comb_type GRUB_UNICODE_COMB_HEBREW_SHIN_DOT = 24, GRUB_UNICODE_COMB_HEBREW_SIN_DOT = 25, GRUB_UNICODE_COMB_HEBREW_VARIKA = 26, + GRUB_UNICODE_COMB_ARABIC_FATHATAN = 27, + GRUB_UNICODE_COMB_ARABIC_DAMMATAN = 28, + GRUB_UNICODE_COMB_ARABIC_KASRATAN = 29, + GRUB_UNICODE_COMB_ARABIC_FATHAH = 30, + GRUB_UNICODE_COMB_ARABIC_DAMMAH = 31, + GRUB_UNICODE_COMB_ARABIC_KASRA = 32, + GRUB_UNICODE_COMB_ARABIC_SHADDA = 33, + GRUB_UNICODE_COMB_ARABIC_SUKUN = 34, GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, diff --git a/normal/charset.c b/normal/charset.c index 6f09fac90..6c68884ae 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -28,9 +28,8 @@ - Indic languages - non-Semitic shaping (rarely used) - Zl and Zp characters - - Combining characters of types 7, 8, 9, 21, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 84, 91, 103, 107, 118, 122, 129, 130, 132, - 218, 224, 226, 233, 234 + - Combining characters of types 7, 8, 9, 21, 35, 36, 84, 91, 103, 107, + 118, 122, 129, 130, 132, 218, 224, 226, 233, 234 - Private use characters (not really a problem) - Variations (no font support) - Vertical text @@ -40,7 +39,7 @@ - Justification data - Glyph posititioning - Baseline data - TODO: Use form characters of Unicode as last resort Arabic shaping. + Most underline diacritics aren't displayed in gfxterm */ /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE @@ -550,6 +549,22 @@ grub_unicode_estimate_width (const struct grub_unicode_glyph *c) #endif +static inline int +is_type_after (enum grub_comb_type a, enum grub_comb_type b) +{ + /* Shadda is numerically higher than most of Arabic diacritics but has + to be rendered before them. */ + if (a == GRUB_UNICODE_COMB_ARABIC_SHADDA + && b <= GRUB_UNICODE_COMB_ARABIC_KASRA + && b >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) + return 0; + if (b == GRUB_UNICODE_COMB_ARABIC_SHADDA + && a <= GRUB_UNICODE_COMB_ARABIC_KASRA + && a >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) + return 1; + return a > b; +} + grub_size_t grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, struct grub_unicode_glyph *out) @@ -605,7 +620,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, out->combining = n; for (j = last_comb_pointer; j < out->ncomb; j++) - if (out->combining[j].type > comb_type) + if (is_type_after (out->combining[j].type, comb_type)) break; grub_memmove (out->combining + j + 1, out->combining + j, From e2588ccbfee10bcc53882baffd97ba11e4308fc0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 13:01:08 +0200 Subject: [PATCH 117/503] Alif and alaph superscripts --- font/font.c | 4 +++- include/grub/unicode.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/font/font.c b/font/font.c index 3aa415cdc..da3f0cc74 100644 --- a/font/font.c +++ b/font/font.c @@ -1248,11 +1248,13 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, min_devwidth = combining_glyphs[i]->width; break; - /* TODO: Put dammah and fathah nearer to shadda. */ + /* TODO: Put dammah, fathah and alif nearer to shadda. */ + case GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH: case GRUB_UNICODE_COMB_ARABIC_DAMMAH: case GRUB_UNICODE_COMB_ARABIC_DAMMATAN: case GRUB_UNICODE_COMB_ARABIC_FATHATAN: case GRUB_UNICODE_COMB_ARABIC_FATHAH: + case GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF: case GRUB_UNICODE_COMB_ARABIC_SUKUN: case GRUB_UNICODE_COMB_ARABIC_SHADDA: case GRUB_UNICODE_COMB_HEBREW_RAFE: diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 19837d82e..f5da907aa 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -114,6 +114,8 @@ enum grub_comb_type GRUB_UNICODE_COMB_ARABIC_KASRA = 32, GRUB_UNICODE_COMB_ARABIC_SHADDA = 33, GRUB_UNICODE_COMB_ARABIC_SUKUN = 34, + GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF = 35, + GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH = 36, GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, From 0546172e3e690d508a90662645a1c4ad7b826e04 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 13:31:03 +0200 Subject: [PATCH 118/503] Basic thaana support --- font/font.c | 20 ++++++++++++++++++++ include/grub/unicode.h | 21 ++++++++++++++++----- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/font/font.c b/font/font.c index da3f0cc74..2eeadbbda 100644 --- a/font/font.c +++ b/font/font.c @@ -1259,6 +1259,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, case GRUB_UNICODE_COMB_ARABIC_SHADDA: case GRUB_UNICODE_COMB_HEBREW_RAFE: case GRUB_UNICODE_STACK_ABOVE: + stacked_above: space = combining_glyphs[i]->offset_y - grub_font_get_xheight (combining_glyphs[i]->font) - 1; if (space <= 0) @@ -1291,6 +1292,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, /* I don't know how ypogegrammeni differs from subscript. */ case GRUB_UNICODE_COMB_YPOGEGRAMMENI: case GRUB_UNICODE_STACK_BELOW: + stacked_below: space = -(combining_glyphs[i]->offset_y + combining_glyphs[i]->height); if (space <= 0) @@ -1303,6 +1305,24 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, min_devwidth = combining_glyphs[i]->width; break; + case GRUB_UNICODE_COMB_MN: + switch (glyph_id->combining[i].code) + { + case GRUB_UNICODE_THAANA_ABAFILI: + case GRUB_UNICODE_THAANA_AABAAFILI: + case GRUB_UNICODE_THAANA_UBUFILI: + case GRUB_UNICODE_THAANA_OOBOOFILI: + case GRUB_UNICODE_THAANA_EBEFILI: + case GRUB_UNICODE_THAANA_EYBEYFILI: + case GRUB_UNICODE_THAANA_OBOFILI: + case GRUB_UNICODE_THAANA_OABOAFILI: + case GRUB_UNICODE_THAANA_SUKUN: + goto stacked_above; + case GRUB_UNICODE_THAANA_IBIFILI: + case GRUB_UNICODE_THAANA_EEBEEFILI: + goto stacked_below; + } + /* Fall through. */ default: { /* Default handling. Just draw combining character on top diff --git a/include/grub/unicode.h b/include/grub/unicode.h index f5da907aa..2e08fb0d1 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -170,11 +170,22 @@ struct grub_unicode_glyph #define GRUB_UNICODE_VARIATION_SELECTOR_16 0xfe0f #define GRUB_UNICODE_VARIATION_SELECTOR_17 0xe0100 #define GRUB_UNICODE_VARIATION_SELECTOR_256 0xe01ef -#define GRUB_UNICODE_HEBREW_WAW 0x05d5 -#define GRUB_UNICODE_ZWNJ 0x200c -#define GRUB_UNICODE_ZWJ 0x200d -#define GRUB_UNICODE_ARABIC_START 0x600 -#define GRUB_UNICODE_ARABIC_END 0x700 +#define GRUB_UNICODE_HEBREW_WAW 0x05d5 +#define GRUB_UNICODE_ZWNJ 0x200c +#define GRUB_UNICODE_ZWJ 0x200d +#define GRUB_UNICODE_ARABIC_START 0x0600 +#define GRUB_UNICODE_ARABIC_END 0x0700 +#define GRUB_UNICODE_THAANA_ABAFILI 0x07a6 +#define GRUB_UNICODE_THAANA_AABAAFILI 0x07a7 +#define GRUB_UNICODE_THAANA_IBIFILI 0x07a8 +#define GRUB_UNICODE_THAANA_EEBEEFILI 0x07a9 +#define GRUB_UNICODE_THAANA_UBUFILI 0x07aa +#define GRUB_UNICODE_THAANA_OOBOOFILI 0x07ab +#define GRUB_UNICODE_THAANA_EBEFILI 0x07ac +#define GRUB_UNICODE_THAANA_EYBEYFILI 0x07ad +#define GRUB_UNICODE_THAANA_OBOFILI 0x07ae +#define GRUB_UNICODE_THAANA_OABOAFILI 0x07af +#define GRUB_UNICODE_THAANA_SUKUN 0x07b0 extern struct grub_unicode_compact_range grub_unicode_compact[]; extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; From 483c5e7d47c260c268853128e4a077211d2e8358 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Mar 2010 13:36:08 +0200 Subject: [PATCH 119/503] Transform remarkable unicode codepoints into enum --- include/grub/unicode.h | 45 ++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 2e08fb0d1..39e4c52cc 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -165,27 +165,30 @@ struct grub_unicode_glyph | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \ | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT) -#define GRUB_UNICODE_COMBINING_GRAPHEME_JOINER 0x34f -#define GRUB_UNICODE_VARIATION_SELECTOR_1 0xfe00 -#define GRUB_UNICODE_VARIATION_SELECTOR_16 0xfe0f -#define GRUB_UNICODE_VARIATION_SELECTOR_17 0xe0100 -#define GRUB_UNICODE_VARIATION_SELECTOR_256 0xe01ef -#define GRUB_UNICODE_HEBREW_WAW 0x05d5 -#define GRUB_UNICODE_ZWNJ 0x200c -#define GRUB_UNICODE_ZWJ 0x200d -#define GRUB_UNICODE_ARABIC_START 0x0600 -#define GRUB_UNICODE_ARABIC_END 0x0700 -#define GRUB_UNICODE_THAANA_ABAFILI 0x07a6 -#define GRUB_UNICODE_THAANA_AABAAFILI 0x07a7 -#define GRUB_UNICODE_THAANA_IBIFILI 0x07a8 -#define GRUB_UNICODE_THAANA_EEBEEFILI 0x07a9 -#define GRUB_UNICODE_THAANA_UBUFILI 0x07aa -#define GRUB_UNICODE_THAANA_OOBOOFILI 0x07ab -#define GRUB_UNICODE_THAANA_EBEFILI 0x07ac -#define GRUB_UNICODE_THAANA_EYBEYFILI 0x07ad -#define GRUB_UNICODE_THAANA_OBOFILI 0x07ae -#define GRUB_UNICODE_THAANA_OABOAFILI 0x07af -#define GRUB_UNICODE_THAANA_SUKUN 0x07b0 +enum + { + GRUB_UNICODE_COMBINING_GRAPHEME_JOINER = 0x034f, + GRUB_UNICODE_HEBREW_WAW = 0x05d5, + GRUB_UNICODE_ARABIC_START = 0x0600, + GRUB_UNICODE_ARABIC_END = 0x0700, + GRUB_UNICODE_THAANA_ABAFILI = 0x07a6, + GRUB_UNICODE_THAANA_AABAAFILI = 0x07a7, + GRUB_UNICODE_THAANA_IBIFILI = 0x07a8, + GRUB_UNICODE_THAANA_EEBEEFILI = 0x07a9, + GRUB_UNICODE_THAANA_UBUFILI = 0x07aa, + GRUB_UNICODE_THAANA_OOBOOFILI = 0x07ab, + GRUB_UNICODE_THAANA_EBEFILI = 0x07ac, + GRUB_UNICODE_THAANA_EYBEYFILI = 0x07ad, + GRUB_UNICODE_THAANA_OBOFILI = 0x07ae, + GRUB_UNICODE_THAANA_OABOAFILI = 0x07af, + GRUB_UNICODE_THAANA_SUKUN = 0x07b0, + GRUB_UNICODE_ZWNJ = 0x200c, + GRUB_UNICODE_ZWJ = 0x200d, + GRUB_UNICODE_VARIATION_SELECTOR_1 = 0xfe00, + GRUB_UNICODE_VARIATION_SELECTOR_16 = 0xfe0f, + GRUB_UNICODE_VARIATION_SELECTOR_17 = 0xe0100, + GRUB_UNICODE_VARIATION_SELECTOR_256 = 0xe01ef + }; extern struct grub_unicode_compact_range grub_unicode_compact[]; extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; From c2062d5f3a568965177e03cac88b0e855320f4c5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 30 Mar 2010 14:09:24 +0200 Subject: [PATCH 120/503] Remove useless change in grub-emu.c --- util/grub-emu.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/util/grub-emu.c b/util/grub-emu.c index debf53b1d..7d4544509 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -63,11 +63,6 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_BAD_MODULE; } -void grub_hostfs_init (void); -void grub_hostfs_fini (void); -void grub_host_init (void); -void grub_host_fini (void); - grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) { @@ -80,14 +75,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) void grub_reboot (void) { - grub_fini_all (); - grub_hostfs_fini (); - grub_host_fini (); - - grub_machine_fini (); - - exit (0); - // longjmp (main_env, 1); + longjmp (main_env, 1); } void @@ -158,6 +146,11 @@ usage (int status) } +void grub_hostfs_init (void); +void grub_hostfs_fini (void); +void grub_host_init (void); +void grub_host_fini (void); + int main (int argc, char *argv[]) { From b07c314e45d85220759a791d74917fefb08440c9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 30 Mar 2010 14:21:48 +0200 Subject: [PATCH 121/503] Add lost unicode LICENSE --- unicode/COPYING | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 unicode/COPYING diff --git a/unicode/COPYING b/unicode/COPYING new file mode 100644 index 000000000..f81c87a27 --- /dev/null +++ b/unicode/COPYING @@ -0,0 +1,9 @@ +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2009 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified. + +THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. From 17be44164beda6dd1b1a57b0869e5faf349a3dcc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 30 Mar 2010 14:22:07 +0200 Subject: [PATCH 122/503] ADd ChangeLog --- ChangeLog.bidi | 223 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 ChangeLog.bidi diff --git a/ChangeLog.bidi b/ChangeLog.bidi new file mode 100644 index 000000000..972e6e356 --- /dev/null +++ b/ChangeLog.bidi @@ -0,0 +1,223 @@ +2010-03-30 Vladimir Serbinenko + + Bidi and diacritics support. + + * Makefile.in (widthspec.bin): New target. + (widthspec.h): Likewise. + (TARGET_CFLAGS): Add -DHAVE_UNIFONT_WIDTHSPEC=1 if font was available. + * autogen.sh: Generate unidata.c. + * commands/cat.c (grub_cmd_cat): Don't use grub_putchar. + * commands/handler.c (grub_cmd_handler): Likewise. + * commands/ls.c (grub_ls_list_devices): Likewise. + (grub_ls_list_files): Likewise. + * commands/minicmd.c (grub_mini_cmd_cat): Likewise. + (grub_mini_cmd_lsmod): Likewise. + * commands/read.c: Likewise. + * kern/corecmd.c (grub_core_cmd_ls): Likewise. + * kern/rescue_reader.c (grub_rescue_read_line): Likewise. + * lib/arg.c (grub_arg_show_help): Likewise. + * lib/crypto.c (grub_password_get): Likewise. + * normal/auth.c (grub_username_get): Likewise. + * normal/misc.c (grub_normal_print_device_info): Likewise. + * commands/help.c (grub_cmd_help): Use grub_unicode_aglomerate_comb. + * conf/common.rmk (grub_mkfont_SOURCES): Add unidata.c. + (gfxmenu_mod_SOURCES): Add gfxmenu/font.c. + (normal/charset.c_DEPENDENCIES): New variable. + (normal_mod_SOURCES): Add normal/charset.c and unidata.c. + (pkglib_MODULES): Remove charset.mod. + (charset_mod_SOURCES): Removed. + (charset_mod_CFLAGS): Likewise. + (charset_mod_LDFLAGS): Likewise. + * font/font.c (ascii_glyph_lookup): Return NULL on failure. + Fill ->font. Reverse ascii bitmaps. + (grub_font_get_xheight): New function. + * font/font.c (grub_font_get_string_width): Moved from here ... + * gfxmenu/font.c (grub_font_get_string_width): ... here. + * font/font.c (grub_font_draw_string): Moved from here ... + * gfxmenu/font.c (grub_font_draw_string): ... here. + * font/font.c (grub_font_dup_glyph): New function. + (grub_font_blit_glyph): Likewise. + (grub_font_blit_glyph_mirror): Likewise. + (blit_comb): Likewise. + (grub_font_construct_dry_run): Likewise. + (grub_font_get_constructed_device_width): Likewise. + (grub_font_construct_glyph): Likewise. + * include/grub/charset.h (grub_ucs4_to_utf8): New proto. + * include/grub/misc.h (grub_utf8_to_ucs4): Moved from here ... + * include/grub/charset.h (grub_utf8_to_ucs4): ... here. + * include/grub/font.h (GRUB_FONT_CODE_CHAR_MASK): New constant. + (GRUB_FONT_CODE_RIGHT_JOINED): Likewise. + (GRUB_FONT_CODE_LEFT_JOINED): Likewise. + (grub_font_get_xheight): New proto. + (grub_font_get_constructed_device_width): Likewise. + (grub_font_construct_glyph): Likewise. + * include/grub/font.h (grub_font_get_string_width): Moved from here ... + * include/grub/gfxmenu_view.h (grub_font_get_string_width): ... here. + * include/grub/font.h (grub_font_draw_string): Moved from here ... + * include/grub/gfxmenu_view.h (grub_font_draw_string): ... here. + * include/grub/i386/vga_common.h (grub_console_putchar): Moved from here.. + * include/grub/i386/pc/console.h (grub_console_putchar): ... here. + * include/grub/i386/vga_common.h (grub_console_real_putchar): Removed. + (grub_console_getcharwidth): Likewise. + * include/grub/misc.h (grub_xputs): New proto. + (grub_puts): Inlined. + * include/grub/normal.h (grub_print_ucs4): Add margin specification. + (grub_normal_get_line_counter): Removed. + (grub_install_newline_hook): Likewise. + (grub_normal_get_char_counter): New proto. + (grub_normal_reset_more): Likewise. + (grub_xputs_normal): Likewise. + * include/grub/term.h (GRUB_TERM_CODE_TYPE_MASK): New definition. + (GRUB_TERM_CODE_TYPE_ASCII): Likewise. + (GRUB_TERM_CODE_TYPE_VGA): Likewise. + (GRUB_TERM_CODE_TYPE_UTF8_LOGICAL): Likewise. + (GRUB_TERM_CODE_TYPE_UTF8_VISUAL): Likewise. + (GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS): Likewise. + (grub_term_output): Pass grub_unicode_glyph to putchar and getcharwidth. + All users updated. + (grub_putchar): Removed. + (grub_putcode): Remove EXPORT_FUNC since it's not in kernel anymore. + (grub_unicode_estimate_width): New function. + (grub_term_getcharwidth): Add defaults. + * include/grub/unicode.h: New file. + * include/grub/video.h (grub_video_signed_rect): New type. + * kern/i386/pc/startup.S (grub_console_real_putchar): Renamed to ... + (grub_console_putchar): ... this. + (grub_console_putchar): Handle argument difference. + * kern/misc.c (grub_puts): Removed. + (grub_vprintf): Store UTF-8 string instead of outputting it directly. + (grub_vsnprintf_real): Remove str = NULL support. + * kern/misc.c (grub_utf8_to_ucs4): Move from here ... + * normal/charset.c (grub_utf8_to_ucs4): ... here. + * kern/term.c (grub_putcode): Renamed to ... + (grub_putcode_dumb): ... this. Pass grub_unicode_glyph instead of code. + (grub_putchar): Removed. + (grub_xputs_dumb): New function. + (grub_xputs): New variable. + (grub_cls): Use grub_putcode_dumb. + * lib/charset.c: Move from here ... + * normal/charset.c: ... to here. + (grub_ucs4_to_utf8): New function. + (grub_ucs4_to_utf8_alloc): Use grub_ucs4_to_utf8. + (join_types): New variable. + (unpack_join): New function. + (bidi_types): New variable. + (unpack_bidi): New function. + (get_bidi_type): Likewise. + (get_join_type): Likewise. + (is_mirrored): Likewise. + (grub_unicode_get_comb_type): Likewise. + (grub_unicode_estimate_width) [HAVE_UNIFONT_WIDTHSPEC]: Likewise. + (is_type_after): Likewise. + (grub_unicode_aglomerate_comb): Likewise. + (bidi_line_wrap): Likewise. + (grub_bidi_line_logical_to_visual): Likewise. + (grub_bidi_logical_to_visual): Likewise. + (grub_unicode_mirror_code): Likewise. + (grub_unicode_shape_code): Likewise. + * normal/cmdline.c (grub_cmdline_get): Reset more counter. + Don't use grub_putchar. + * normal/main.c (grub_normal_init_page): Use grub_putcode. + (grub_normal_reader_init): Likewise. + (grub_xputs_saved): New variable. + (GRUB_MOD_INIT): Set grub_xputs. + (GRUB_MOD_FINI): Restore grub_xputs. + * normal/menu.c (grub_wait_after_message): Don't use grub_putchar. + (menu_init): Avoid printing gfxmenu error. + (show_menu): Use grub_normal_get_char_counter. + * normal/menu_entry.c (update_screen): Fix out-of-array. + (complete): Avoid NULL dereferencing. + * grub_menu_entry_run (grub_menu_entry_run): Don't use putchar. + * normal/menu_text.c (print_spaces): Removed. + (grub_print_ucs4): Likewise. + (grub_print_message_indented): Use grub_print_ucs4. + (print_message): Use grub_putcode. + (print_entry): Hanlde diacritics. + * normal/term.c (term_state): New type. + (grub_more_lines): Removed. + (term_states): New variable. + (grub_normal_line_counter): Renamed to .. + (grub_normal_char_counter): ...this. All users updated. + (grub_normal_get_line_counter): Renamed to ... + (grub_normal_get_char_counter): ... this. + (grub_normal_reset_more): New function. + (process_newline): Removed. + (print_more): New function. + (grub_install_newline_hook): Removed. + (map_code): New function. + (grub_puts_terminal): Use grub_print_ucs4. + (putglyph): New function. + (putcode_real): Likewise. + (grub_putcode): Use putcode_real. + (get_maxwidth): New function. + (get_startwidth): Likewise. + (print_ucs4_terminal): Likewise. + (find_term_state): Likewise. + (put_glyphs_terminal): Likewise. + (print_backlog): Likewise. + (print_ucs4_real): Likewise. + (grub_print_ucs4): Likewise. + (grub_xputs_normal): Likewise. + * term/efi/console.c (grub_console_putchar): Output diacritics. + (grub_console_getcharwidth): Removed. + (grub_console_term_output): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL. + * term/gfxterm.c (clear_char): Free chars. + (scroll_up): Avoid leaking memory. + (grub_gfxterm_putchar): Support diacritics. + (grub_video_term): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL. + * term/i386/pc/console.c (grub_console_term_output): Declare as + GRUB_TERM_CODE_TYPE_VGA. + * term/i386/pc/vga.c (grub_vga_term): Declare as + GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS. + * term/i386/pc/vga_text.c (grub_vga_text_term): Declare as + GRUB_TERM_CODE_TYPE_VGA. + * term/i386/vga_common.c (map_char): Removed. + (grub_console_putchar): Likewise. + (grub_console_getcharwidth): Likewise. + * term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Remove mapping. + (grub_ofconsole_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII. + * term/serial.c (options): New options ascii, utf8 and visual-utf8. + (grub_serial_putchar): Remove mapping. Use estimated_width. + (grub_cmd_serial): Handle charset arguments. + * term/terminfo.c (putstr): Use putchar directly. + * unicode/ArabicShaping.txt: New file (imported from Unicode). + * unicode/BidiMirroring.txt: Likewise. + * unicode/UnicodeData.txt: Likewise. + * unicode/COPYING: Likewise. + * util/console.c (grub_ncurses_putchar): Remove mapping. + (grub_ncurses_getcharwidth): Removed. + (grub_ncurses_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII. + * util/grub-editenv.c (grub_putchar): Removed. + (grub_xputs_real): New function. + (grub_xputs): New variable. + * util/grub-fstest.c (grub_putchar): Removed. + (grub_xputs_real): New function. + (grub_xputs): New variable. + * util/grub-probe.c (grub_putchar): Removed. + (grub_xputs_real): New function. + (grub_xputs): New variable. + * util/grub-script-check.c (grub_putchar): Removed. + (grub_xputs_real): New function. + (grub_xputs): New variable. + * util/i386/pc/grub-setup.c (grub_putchar): Removed. + (grub_xputs_real): New function. + (grub_xputs): New variable. + * util/import_unicode.py: New file. + * util/grub-mkfont.c (ft_errmsgs): New array. + (grub_glyph_info): Make bitmap a pointer. + (file_formats): New type WIDTH_SPEC. + (grub_font_info): New members glyphs_unsorted, glyphs_sorted, num_glyphs. + (options): Add width-spec. + (help): Likewise. + (add_char): Renamed to ... + (add_glyph): ... this. + (add_glyph): Use index. Show freetype errors. Cut blank space at borders. + (glyph_replace): New type. + (subst_rightjoin), (subst_leftjoin), (subst_medijoin): New variables. + (add_char): New function. + (add_subst): Likewise. + (process_cursive): Likewise. + (add_font): Handle GSUB. + (write_font_width_spec): New function. + (main): Sort glyphs. + From 04a3792f87113f34b7fe3bfce3bdf347cb19ff84 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 5 Apr 2010 22:39:58 +0200 Subject: [PATCH 123/503] Macroify fwstart.S more --- include/grub/mips/loongson.h | 3 +++ include/grub/mips/yeeloong/serial.h | 1 + kern/mips/yeeloong/fwstart.S | 24 +++++++++++++----------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index c2aa276a2..7dcc15cd4 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -67,6 +67,9 @@ #define GRUB_CPU_LOONGSON_LIOCFG 0xbfe00108 #define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2 #define GRUB_CPU_LOONGSON_ROM_DELAY_MASK 0x1f +#define GRUB_CPU_LOONGSON_CORECFG 0xbfe00180 +#define GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE 0x100 +#define GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU 0x200 #define GRUB_CPU_LOONGSON_GPIOCFG 0xbfe00120 #define GRUB_CPU_LOONGSON_SHUTDOWN_GPIO 1 diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/yeeloong/serial.h index b22352f5a..ebe3638a1 100644 --- a/include/grub/mips/yeeloong/serial.h +++ b/include/grub/mips/yeeloong/serial.h @@ -19,6 +19,7 @@ #ifndef GRUB_MACHINE_SERIAL_HEADER #define GRUB_MACHINE_SERIAL_HEADER 1 +#define GRUB_MACHINE_SERIAL_DIVISOR_115200 2 #define GRUB_MACHINE_SERIAL_PORT 0xbff003f8 #ifndef ASM_FILE diff --git a/kern/mips/yeeloong/fwstart.S b/kern/mips/yeeloong/fwstart.S index 4a9a749f7..f541a535f 100644 --- a/kern/mips/yeeloong/fwstart.S +++ b/kern/mips/yeeloong/fwstart.S @@ -116,17 +116,19 @@ __start: move $a0, $v0 bal read_spd - ori $a0, $zero, 2 + ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 lui $a0, %hi(unimplemented_memory_type) bne $t0, $v0, fatal addiu $a0, $a0, %hi(unimplemented_memory_type) /* And here is our goal: DDR2 controller initialisation. */ - lui $t0, 0xbfe0 - ld $t1, 0x0180($t0) - andi $t1, $t1, 0x4ff - sd $t1, 0x0180($t0) + lui $t0, %hi(GRUB_CPU_LOONGSON_CORECFG) + ld $t1, %lo(GRUB_CPU_LOONGSON_CORECFG) ($t0) + /* Use addiu for sign-extension. */ + addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE|GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU) + and $t1, $t1, $t2 + sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) b continue @@ -218,7 +220,7 @@ serial_hw_init: sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0) /* Set the baud rate 115200. */ - ori $t1, $zero, 2 + ori $t1, $zero, GRUB_MACHINE_SERIAL_DIVISOR_115200 sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLL)($t0) sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLH)($t0) @@ -430,7 +432,7 @@ regdump: write_dumpreg: ld $t2, 0($t6) sd $t2, 0($t4) - addiu $t4, $t4, 0x10 + addiu $t4, $t4, GRUB_MACHINE_DDR2_REG_STEP jr $ra addiu $t6, $t6, GRUB_MACHINE_DDR2_REG_SIZE @@ -531,10 +533,10 @@ continue: sd $t5, (%lo(GRUB_MACHINE_DDR2_BASE) + 0x30) ($t4) /* Desactivate DDR2 registers. */ - lui $t0, 0xbfe0 - ld $t1, 0x0180($t0) - ori $t1, $t1, 0x100 - sd $t1, 0x0180($t0) + lui $t0, %hi (GRUB_CPU_LOONGSON_CORECFG) + ld $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) + ori $t1, $t1, GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE + sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) /* Enable cache. */ mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG From f9e7780cfff7fad076c23c73a930f3bb5b33fcee Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 6 Apr 2010 02:40:44 +0200 Subject: [PATCH 124/503] Fix an early timer-related hang --- include/grub/cs5536.h | 9 +++++++++ kern/mips/yeeloong/init.c | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index ec554f002..21d6d55fc 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -29,8 +29,12 @@ #define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 #define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 #define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc +#define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008 #define GRUB_CS5536_MSR_SMB_BAR 0x8000000b #define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c +#define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d +#define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e +#define GRUB_CS5536_MSR_PM_BAR 0x8000000f #define GRUB_CS5536_SMB_REG_DATA 0x0 #define GRUB_CS5536_SMB_REG_STATUS 0x1 #define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) @@ -55,10 +59,15 @@ #define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8) #define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000) #define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000) +#define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK) /* PMON-compatible LBARs. */ +#define GRUB_CS5536_LBAR_IRQ_MAP 0x0b360 #define GRUB_CS5536_LBAR_GPIO 0x0b000 +#define GRUB_CS5536_LBAR_MFGPT 0x0b300 #define GRUB_CS5536_LBAR_SMBUS 0x0b390 +#define GRUB_CS5536_LBAR_ACPI 0x0b340 +#define GRUB_CS5536_LBAR_PM 0x0b280 #define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) #define GRUB_GPIO_REG_OUT_EN 0x4 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 127cf870e..9cadd64b2 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -67,6 +67,26 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, return GRUB_ERR_NONE; } +/* Dump of GPIO connections. FIXME: Remove useless and macroify. */ +static grub_uint32_t gpiodump[] = { + 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000, + 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000, + 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000, + 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000, + 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000, + 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000, + 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x50000000, 0x00000000, 0x00000000, +}; + void grub_machine_init (void) { @@ -121,6 +141,27 @@ grub_machine_init (void) grub_arch_memsize = (totalmem >> 20); grub_arch_highmemsize = 0; } + + /* Make sure GPIO is where we expect it to be. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR, + GRUB_CS5536_LBAR_TURN_ON + | GRUB_CS5536_LBAR_GPIO); + + for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++) + ((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE + + GRUB_CS5536_LBAR_GPIO)) [i] + = gpiodump[i]; + + /* Enable more BARs. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR, + GRUB_CS5536_LBAR_TURN_ON + | GRUB_CS5536_LBAR_IRQ_MAP); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_MFGPT_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_MFGPT); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_ACPI_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); } modend = grub_modules_get_end (); From 781d7798bb2fa0f04c455fe5df1f72b4255b589b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 6 Apr 2010 22:12:04 +0200 Subject: [PATCH 125/503] Fix interrupt and windows problems --- disk/ata.c | 6 +- include/grub/ata.h | 6 ++ include/grub/cs5536.h | 96 ++++++++++++++++++++-- include/grub/mips/yeeloong/pci.h | 5 +- kern/mips/yeeloong/init.c | 131 +++++++++++++++++++++++++++++++ 5 files changed, 234 insertions(+), 10 deletions(-) diff --git a/disk/ata.c b/disk/ata.c index b2291cd53..1b55ee680 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -27,8 +27,10 @@ #include /* At the moment, only two IDE ports are supported. */ -static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; -static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; +static const grub_port_t grub_ata_ioaddress[] = { GRUB_ATA_CH0_PORT1, + GRUB_ATA_CH1_PORT1 }; +static const grub_port_t grub_ata_ioaddress2[] = { GRUB_ATA_CH0_PORT2, + GRUB_ATA_CH1_PORT2 }; static struct grub_ata_device *grub_ata_devices; diff --git a/include/grub/ata.h b/include/grub/ata.h index 940e67102..9e3aaf0e6 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -32,6 +32,12 @@ typedef enum GRUB_ATA_LBA48 } grub_ata_addressing_t; +#define GRUB_ATA_CH0_PORT1 0x1f0 +#define GRUB_ATA_CH1_PORT1 0x170 + +#define GRUB_ATA_CH0_PORT2 0x3f6 +#define GRUB_ATA_CH1_PORT2 0x376 + #define GRUB_ATA_REG_DATA 0 #define GRUB_ATA_REG_ERROR 1 #define GRUB_ATA_REG_FEATURES 1 diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index 21d6d55fc..c2323fe9b 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -31,10 +31,92 @@ #define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc #define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008 #define GRUB_CS5536_MSR_SMB_BAR 0x8000000b + +#define GRUB_CS5536_SMBUS_REGS_SIZE 8 +#define GRUB_CS5536_GPIO_REGS_SIZE 256 +#define GRUB_CS5536_MFGPT_REGS_SIZE 64 +#define GRUB_CS5536_IRQ_MAP_REGS_SIZE 32 +#define GRUB_CS5536_PM_REGS_SIZE 128 +#define GRUB_CS5536_ACPI_REGS_SIZE 32 + +#define GRUB_CS5536_DESTINATION_GLIU 0 +#define GRUB_CS5536_DESTINATION_GLPCI_SB 1 +#define GRUB_CS5536_DESTINATION_USB 2 +#define GRUB_CS5536_DESTINATION_IDE 3 +#define GRUB_CS5536_DESTINATION_DD 4 +#define GRUB_CS5536_DESTINATION_ACC 5 +#define GRUB_CS5536_DESTINATION_GLCP 7 + +#define GRUB_CS5536_P2D_DEST_SHIFT 61 +#define GRUB_CS5536_P2D_LOG_ALIGN 12 +#define GRUB_CS5536_P2D_ALIGN (1 << GRUB_CS5536_P2D_LOG_ALIGN) +#define GRUB_CS5536_P2D_BASE_SHIFT 20 +#define GRUB_CS5536_P2D_MASK_SHIFT 0 + +#define GRUB_CS5536_MSR_GL_IOD_START 0x000100e0 +#define GRUB_CS5536_IOD_DEST_SHIFT 61 +#define GRUB_CS5536_IOD_BASE_SHIFT 20 +#define GRUB_CS5536_IOD_MASK_SHIFT 0 +#define GRUB_CS5536_IOD_ADDR_MASK 0xfffff + #define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c #define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d #define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e #define GRUB_CS5536_MSR_PM_BAR 0x8000000f +#define GRUB_CS5536_MSR_DIVIL_LEG_IO 0x80000014 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 0x00000001 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1 0x00000002 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 0x10000000 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP 0x04000000 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK 0x80000024 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK 0x80000025 +#define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002 +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL 0x8000004e +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE 0x80 + +#define GRUB_CS5536_MSR_USB_OHCI_BASE 0x40000008 +#define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009 +#define GRUB_CS5536_MSR_USB_CONTROLLER_BASE 0x4000000a +#define GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE 0x4000000b +#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0xffffff00 +#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x400000000ULL +#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x200000000ULL +#define GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40 + +#define GRUB_CS5536_MSR_IDE_IO_BAR 0x60000008 +#define GRUB_CS5536_MSR_IDE_IO_BAR_UNITS 1 +#define GRUB_CS5536_MSR_IDE_IO_BAR_ADDR_MASK 0xfffffff0 +#define GRUB_CS5536_MSR_IDE_CFG 0x60000010 +#define GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE 2 +#define GRUB_CS5536_MSR_IDE_TIMING 0x60000012 +#define GRUB_CS5536_MSR_IDE_TIMING_PIO0 0x98 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT 16 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING 0x60000013 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 0x99 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT 6 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT 4 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 2 + +#define GRUB_CS5536_MSR_GL_PCI_CTRL 0x00000010 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE 1 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE 2 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT 35 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT 60 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT 56 + +#define GRUB_CS5536_MSR_GL_REGIONS_START 0x00000020 +#define GRUB_CS5536_MSR_GL_REGIONS_NUM 16 +#define GRUB_CS5536_MSR_GL_REGION_ENABLE 1 +#define GRUB_CS5536_MSR_GL_REGION_IO 0x100000000ULL +#define GRUB_CS5536_MSR_GL_REGION_BASE_MASK 0xfffff000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT 12 +#define GRUB_CS5536_MSR_GL_REGION_TOP_MASK 0xfffff00000000000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT 44 + +#define GRUB_CS5536_MSR_GL_P2D_START 0x00010020 + #define GRUB_CS5536_SMB_REG_DATA 0x0 #define GRUB_CS5536_SMB_REG_STATUS 0x1 #define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) @@ -62,12 +144,14 @@ #define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK) /* PMON-compatible LBARs. */ -#define GRUB_CS5536_LBAR_IRQ_MAP 0x0b360 -#define GRUB_CS5536_LBAR_GPIO 0x0b000 -#define GRUB_CS5536_LBAR_MFGPT 0x0b300 -#define GRUB_CS5536_LBAR_SMBUS 0x0b390 -#define GRUB_CS5536_LBAR_ACPI 0x0b340 -#define GRUB_CS5536_LBAR_PM 0x0b280 +#define GRUB_CS5536_LBAR_GPIO 0xb000 +#define GRUB_CS5536_LBAR_ACC 0xb200 +#define GRUB_CS5536_LBAR_PM 0xb280 +#define GRUB_CS5536_LBAR_MFGPT 0xb300 +#define GRUB_CS5536_LBAR_ACPI 0xb340 +#define GRUB_CS5536_LBAR_IRQ_MAP 0xb360 +#define GRUB_CS5536_LBAR_IDE 0xb380 +#define GRUB_CS5536_LBAR_SMBUS 0xb390 #define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) #define GRUB_GPIO_REG_OUT_EN 0x4 diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index aa5e0bbea..8f3a29d5c 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -27,8 +27,9 @@ #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 -#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 -#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 +#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000 #define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR 0xbfe00118 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 9cadd64b2..cf241ea96 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -31,6 +31,7 @@ #include #include #include +#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); @@ -87,6 +88,43 @@ static grub_uint32_t gpiodump[] = { 0x00000000, 0x50000000, 0x00000000, 0x00000000, }; +static inline void +set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start, + grub_uint16_t len) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_REGIONS_START + num, + ((((grub_uint64_t) start + len - 4) + << GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT) + & GRUB_CS5536_MSR_GL_REGION_TOP_MASK) + | (((grub_uint64_t) start + << GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT) + & GRUB_CS5536_MSR_GL_REGION_BASE_MASK) + | GRUB_CS5536_MSR_GL_REGION_IO + | GRUB_CS5536_MSR_GL_REGION_ENABLE); +} + +static inline void +set_iod (grub_pci_device_t dev, int num, int dest, int start, int mask) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_IOD_START + num, + ((grub_uint64_t) dest << GRUB_CS5536_IOD_DEST_SHIFT) + | (((grub_uint64_t) start & GRUB_CS5536_IOD_ADDR_MASK) + << GRUB_CS5536_IOD_BASE_SHIFT) + | ((mask & GRUB_CS5536_IOD_ADDR_MASK) + << GRUB_CS5536_IOD_MASK_SHIFT)); +} + +static inline void +set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_P2D_START + num, + (((grub_uint64_t) dest) << GRUB_CS5536_P2D_DEST_SHIFT) + | ((grub_uint64_t) (start >> GRUB_CS5536_P2D_LOG_ALIGN) + << GRUB_CS5536_P2D_BASE_SHIFT) + | (((1 << (32 - GRUB_CS5536_P2D_LOG_ALIGN)) - 1) + << GRUB_CS5536_P2D_MASK_SHIFT)); +} + void grub_machine_init (void) { @@ -147,6 +185,7 @@ grub_machine_init (void) GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_GPIO); + /* Setup GPIO. */ for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++) ((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)) [i] @@ -162,6 +201,98 @@ grub_machine_init (void) GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI); grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR, GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); + + /* Setup DIVIL. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, + GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK, + (~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK, + GRUB_CS5536_DIVIL_LPC_INTERRUPTS); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL, + GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE); + + /* Initialise USB controller. */ + /* FIXME: assign adresses dynamically. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | 0x05024000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | (0x20ULL + << GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT) + | 0x05023000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_CONTROLLER_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | 0x05020000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE, + GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | 0x05022000); + set_p2d (dev, 0, GRUB_CS5536_DESTINATION_USB, 0x05020000); + set_p2d (dev, 1, GRUB_CS5536_DESTINATION_USB, 0x05022000); + set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000); + set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000); + + /* Setup IDE controller. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR, + GRUB_CS5536_LBAR_IDE + | GRUB_CS5536_MSR_IDE_IO_BAR_UNITS); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CFG, + GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_TIMING, + (GRUB_CS5536_MSR_IDE_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT) + | (GRUB_CS5536_MSR_IDE_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT)); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CAS_TIMING, + (GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT) + | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT) + | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT)); + + /* Setup Geodelink PCI. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_PCI_CTRL, + (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT) + | (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT) + | (8ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT) + | GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE + | GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE); + + /* Setup windows. */ + set_io_space (dev, 0, GRUB_CS5536_LBAR_SMBUS, + GRUB_CS5536_SMBUS_REGS_SIZE); + set_io_space (dev, 1, GRUB_CS5536_LBAR_GPIO, GRUB_CS5536_GPIO_REGS_SIZE); + set_io_space (dev, 2, GRUB_CS5536_LBAR_MFGPT, + GRUB_CS5536_MFGPT_REGS_SIZE); + set_io_space (dev, 3, GRUB_CS5536_LBAR_IRQ_MAP, + GRUB_CS5536_IRQ_MAP_REGS_SIZE); + set_io_space (dev, 4, GRUB_CS5536_LBAR_PM, GRUB_CS5536_PM_REGS_SIZE); + set_io_space (dev, 5, GRUB_CS5536_LBAR_ACPI, GRUB_CS5536_ACPI_REGS_SIZE); + set_iod (dev, 0, GRUB_CS5536_DESTINATION_IDE, GRUB_ATA_CH0_PORT1, + 0xffff8); + set_iod (dev, 1, GRUB_CS5536_DESTINATION_ACC, GRUB_CS5536_LBAR_ACC, + 0xfff80); + set_iod (dev, 2, GRUB_CS5536_DESTINATION_IDE, GRUB_CS5536_LBAR_IDE, + 0xffff0); + + /* Setup PCI controller. */ + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_COMMAND)) = 0x22b00046; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_CACHELINE)) = 0xff; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_ADDRESS_REG0)) + = 0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 | GRUB_PCI_ADDR_MEM_PREFETCH; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_ADDRESS_REG1)) = 0; } modend = grub_modules_get_end (); From 3bf09c9ea83350ee0be9c970ddbb8a57606f3eb5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 6 Apr 2010 22:23:02 +0200 Subject: [PATCH 126/503] rename format from raw to yeeloong_flash --- include/grub/mips/kernel.h | 13 ------------- include/grub/mips/qemu-mips/kernel.h | 15 +++++++++++++++ include/grub/mips/yeeloong/kernel.h | 13 +++++++++++++ util/grub-mkrawimage.c | 5 +++++ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 8b68f7b6b..ee759f10b 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -41,21 +41,8 @@ #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/mips/qemu-mips/kernel.h b/include/grub/mips/qemu-mips/kernel.h index dbf74c1b2..cc6169d5f 100644 --- a/include/grub/mips/qemu-mips/kernel.h +++ b/include/grub/mips/qemu-mips/kernel.h @@ -31,6 +31,21 @@ void EXPORT_FUNC (grub_halt) (void); configuration file are located. */ extern char grub_prefix[]; +#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW + +#ifndef ASM_FILE + +typedef enum { + GRUB_PLATFORM_IMAGE_RAW, + GRUB_PLATFORM_IMAGE_ELF +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW +#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF + #endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 230455dbf..05fe0eb55 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -27,6 +27,19 @@ void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); +#define GRUB_PLATFORM_IMAGE_FORMATS "yeeloong_flash, elf" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "yeeloong_flash" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_YEELOONG_FLASH + +typedef enum { + GRUB_PLATFORM_IMAGE_YEELOONG_FLASH, + GRUB_PLATFORM_IMAGE_ELF +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_YEELOONG_FLASH GRUB_PLATFORM_IMAGE_YEELOONG_FLASH +#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF + #endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 7babbef6a..67bd64a1b 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -569,6 +569,11 @@ main (int argc, char *argv[]) #ifdef GRUB_PLATFORM_IMAGE_DEFAULT case 'O': +#ifdef GRUB_PLATFORM_IMAGE_YEELOONG_FLASH + if (strcmp (optarg, "yeeloong_flash") == 0) + format = GRUB_PLATFORM_IMAGE_YEELOONG_FLASH; + else +#endif #ifdef GRUB_PLATFORM_IMAGE_RAW if (strcmp (optarg, "raw") == 0) format = GRUB_PLATFORM_IMAGE_RAW; From 1d383404e30b0759d6054db3ff289f6b7e3c1778 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 19:30:57 +0200 Subject: [PATCH 127/503] compile fixes and cleanups --- kern/term.c | 2 -- normal/charset.c | 2 +- term/efi/console.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/kern/term.c b/kern/term.c index a65d67196..dba94ecf7 100644 --- a/kern/term.c +++ b/kern/term.c @@ -28,8 +28,6 @@ struct grub_term_input *grub_term_inputs_disabled; struct grub_term_output *grub_term_outputs; struct grub_term_input *grub_term_inputs; -void (*grub_newline_hook) (void) = NULL; - /* Put a Unicode character. */ static void grub_putcode_dumb (grub_uint32_t code, diff --git a/normal/charset.c b/normal/charset.c index 6c68884ae..0fcc2a440 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -1254,7 +1254,7 @@ grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr) for (i = 0; grub_unicode_arabic_shapes[i].code; i++) if (grub_unicode_arabic_shapes[i].code == in) { - grub_uint32_t out; + grub_uint32_t out = 0; switch (attr & (GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)) { diff --git a/term/efi/console.c b/term/efi/console.c index 35b265ddb..aa0c984c2 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -350,7 +350,7 @@ static struct grub_term_output grub_console_term_output = .setcolor = grub_console_setcolor, .getcolor = grub_console_getcolor, .setcursor = grub_console_setcursor, - .flags = GRUB_TERM_CODE_TYPE_UCS4_VISUAL + .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS }; void From 787928e31e8ee281935870014b5466abdd05f401 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 23:15:33 +0200 Subject: [PATCH 128/503] Remove newline_hook declaration --- include/grub/term.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index 8a9218635..40f7fb0b9 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -427,8 +427,6 @@ grub_term_getcolor (struct grub_term_output *term, } } -extern void (*EXPORT_VAR (grub_newline_hook)) (void); - struct grub_term_autoload { struct grub_term_autoload *next; From e2d15128a5a2468a5ce9db7c441810e0defae56e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 23:16:08 +0200 Subject: [PATCH 129/503] Fix grub-setup on sparc compilation --- conf/sparc64-ieee1275.rmk | 2 +- util/sparc64/ieee1275/grub-setup.c | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 78e511e31..ba891307a 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -51,7 +51,7 @@ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/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/err.c kern/misc.c kern/partition.c \ kern/file.c kern/fs.c kern/env.c kern/list.c \ fs/fshelp.c \ \ diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index c39ea853f..b5aa3ca85 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -82,21 +82,20 @@ struct boot_blocklist grub_uint32_t len; } __attribute__ ((packed)); -void -grub_putchar (int c) +void +grub_xputs_real (const char *str) { - putchar (c); + fputs (str, stdout); } +void (*grub_xputs) (const char *str) = grub_xputs_real; + int grub_getkey (void) { return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { From b02c7c8fb57a92cd04a84d32bb67c6142980f144 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 12 Apr 2010 21:33:03 +0530 Subject: [PATCH 130/503] added getopt like error for missing option parameters --- util/grub-install.in | 27 ++++++++++++++++++-------- util/grub-mkconfig.in | 19 +++++++++++++++--- util/grub-mkrescue.in | 19 ++++++++++++++---- util/grub-reboot.in | 13 ++++++++++++- util/grub-set-default.in | 13 ++++++++++++- util/i386/efi/grub-install.in | 21 +++++++++++++++----- util/ieee1275/grub-install.in | 21 +++++++++++++++----- util/powerpc/ieee1275/grub-mkrescue.in | 17 +++++++++++++--- 8 files changed, 120 insertions(+), 30 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index 7b9c04913..e5ed9dcd5 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -105,6 +105,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + # Check the arguments. while test $# -gt 0 do @@ -120,37 +131,37 @@ do exit 0 ;; --modules) - modules=$1; shift;; + modules=`argument $option "$@"`; shift;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; --font) - font=$1; shift;; + font=`argument $option "$@"`; shift;; --font=*) font=`echo "$option" | sed 's/--font=//'` ;; --root-directory) - rootdir=$1; shift;; + rootdir=`argument $option "$@"`; shift;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; --grub-setup) - grub_setup=$1; shift;; + grub_setup=`argument $option "$@"`; shift;; --grub-setup=*) grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;; --grub-mkimage) - grub_mkimage=$1; shift;; + grub_mkimage=`argument $option "$@"`; shift;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; --grub-mkdevicemap) - grub_mkdevicemap=$1; shift;; + grub_mkdevicemap=`argument $option "$@"`; shift;; --grub-mkdevicemap=*) grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; --grub-probe) - grub_probe=$1; shift;; + grub_probe=`argument $option "$@"`; shift;; --grub-probe=*) grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; @@ -161,7 +172,7 @@ do --disk-module) if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then - disk_module=$1; shift; + disk_module=`argument $option "$@"`; shift; fi ;; --disk-module=*) if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 82964836b..c3aa57723 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -49,6 +49,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + # Check the arguments. while test $# -gt 0 do @@ -63,9 +74,7 @@ do echo "$0 (GNU GRUB ${package_version})" exit 0 ;; -o | --output) - grub_cfg=$1 - shift - ;; + grub_cfg=`argument $option "$@"`; shift;; --output=*) grub_cfg=`echo "$option" | sed 's/--output=//'` ;; @@ -74,6 +83,10 @@ do usage exit 1 ;; + *) + echo "Invalid parameter, $option" 1>&2 + exit 1 + ;; esac done diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 64ccd6ae8..ffb987718 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -51,6 +51,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + # Check the arguments. while test $# -gt 0 do @@ -66,18 +77,18 @@ do exit 0 ;; --modules) - modules=$1; shift ;; + modules=`argument $option "$@"`; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; -o | --output) - output_image=$1; shift ;; + output_image=`argument $option "$@"`; shift ;; --output=*) output_image=`echo "$option" | sed 's/--output=//'` ;; # Intentionally undocumented --override-directory) - override_dir=$1 + override_dir=`argument $option "$@"` shift PATH=${override_dir}:$PATH export PATH @@ -93,7 +104,7 @@ do exit 1 ;; *) - source="${source} ${option}" ;; + source="${source} ${option} $@"; break ;; esac done diff --git a/util/grub-reboot.in b/util/grub-reboot.in index eb7073e02..48e3ae243 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -44,6 +44,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + # Check the arguments. while test $# -gt 0 do @@ -59,7 +70,7 @@ do exit 0 ;; --root-directory) - rootdir=$1; shift ;; + rootdir=`argument $option "$@"`; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; diff --git a/util/grub-set-default.in b/util/grub-set-default.in index 2636543c3..a4739f95f 100644 --- a/util/grub-set-default.in +++ b/util/grub-set-default.in @@ -44,6 +44,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + # Check the arguments. while test $# -gt 0 do @@ -59,7 +70,7 @@ do exit 0 ;; --root-directory) - rootdir=$1; shift ;; + rootdir=`argument $option "$@"`; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index 097519d50..54c190678 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -71,6 +71,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + # Check the arguments. while test $# -gt 0 do @@ -86,27 +97,27 @@ do exit 0 ;; --modules) - modules=$1; shift ;; + modules=`argument $option "$@"`; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; --root-directory) - rootdir=$1; shift ;; + rootdir=`argument $option "$@"`; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; --grub-mkimage) - grub_mkimage=$1; shift ;; + grub_mkimage=`argument $option "$@"`; shift ;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; --grub-mkdevicemap) - grub_mkdevicemap=$1; shift ;; + grub_mkdevicemap=`argument $option "$@"`; shift ;; --grub-mkdevicemap=*) grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; --grub-probe) - grub_probe=$1; shift ;; + grub_probe=`argument $option "$@"`; shift ;; --grub-probe=*) grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 4a5403c18..dde275c2a 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -74,6 +74,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + # Check the arguments. while test $# -gt 0 do @@ -89,27 +100,27 @@ do exit 0 ;; --modules) - modules=$1; shift ;; + modules=`argument $option "$@"`; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; --root-directory) - rootdir=$1; shift ;; + rootdir=`argument $option "$@"`; shift ;; --root-directory=*) rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; --grub-mkdevicemap) - grub_mkdevicemap=$1; shift ;; + grub_mkdevicemap=`argument $option "$@"`; shift ;; --grub-mkdevicemap=*) grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; --grub-mkimage) - grub_mkimage=$1; shift ;; + grub_mkimage=`argument $option "$@"`; shift ;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; --grub-probe) - grub_probe=$1; shift ;; + grub_probe=`argument $option "$@"`; shift ;; --grub-probe=*) grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index 375adb0cb..1adc149ae 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -52,6 +52,17 @@ Report bugs to . EOF } +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + input_dir=${pkglibdir} # Check the arguments. @@ -69,17 +80,17 @@ do exit 0 ;; --modules) - modules=$1; shift ;; + modules=`argument $option "$@"`; shift ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; --pkglibdir) - input_dir=$1; shift ;; + input_dir=`argument $option "$@"`; shift ;; --pkglibdir=*) input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;; --grub-mkimage) - grub_mkimage=$1; shift ;; + grub_mkimage=`argument $option "$@"`; shift ;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; From d499b1337144d3811410159d466c78ce9bd02657 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Apr 2010 02:13:28 +0200 Subject: [PATCH 131/503] Remove grub/handler.h inclusion. Reported by: Giovanni Toraldo --- util/grub-editenv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/util/grub-editenv.c b/util/grub-editenv.c index f21042c97..4ea97bded 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include From 1c9d6bb81b49ef776dde560ac13cb3222f14c25e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 16 Apr 2010 19:43:52 +0200 Subject: [PATCH 132/503] Initialise USB option controller --- include/grub/cs5536.h | 13 ++++++++++--- kern/mips/yeeloong/init.c | 13 +++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index c2323fe9b..218e17d1a 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -39,6 +39,11 @@ #define GRUB_CS5536_PM_REGS_SIZE 128 #define GRUB_CS5536_ACPI_REGS_SIZE 32 +#define GRUB_CS5536_USB_OPTION_REGS_SIZE 0x1c +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX 1 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK 0x03 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC 0x02 + #define GRUB_CS5536_DESTINATION_GLIU 0 #define GRUB_CS5536_DESTINATION_GLPCI_SB 1 #define GRUB_CS5536_DESTINATION_USB 2 @@ -78,9 +83,11 @@ #define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009 #define GRUB_CS5536_MSR_USB_CONTROLLER_BASE 0x4000000a #define GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE 0x4000000b -#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0xffffff00 -#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x400000000ULL -#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x200000000ULL +#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0x00ffffff00ULL +#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x0400000000ULL +#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x0200000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_ENABLED 0x0800000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_STATUS 0x1000000000ULL #define GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40 #define GRUB_CS5536_MSR_IDE_IO_BAR 0x60000008 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index cf241ea96..5c3340f39 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -239,6 +239,19 @@ grub_machine_init (void) set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000); set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000); + { + volatile grub_uint32_t *oc; + oc = grub_pci_device_map_range (dev, 0x05022000, + GRUB_CS5536_USB_OPTION_REGS_SIZE); + + oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] = + (oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] + & ~GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK) + | GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC; + grub_pci_device_unmap_range (dev, oc, GRUB_CS5536_USB_OPTION_REGS_SIZE); + } + + /* Setup IDE controller. */ grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR, GRUB_CS5536_LBAR_IDE From 913043335344de534fa70205f6c823090b707a0a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 16 Apr 2010 19:46:22 +0200 Subject: [PATCH 133/503] Enable USB compilation on Yeeloong --- conf/mips-yeeloong.rmk | 34 ++++++++++++++++++++++++++++++-- include/grub/cs5536.h | 8 +++++--- include/grub/mips/yeeloong/pci.h | 10 +++++----- term/usb_keyboard.c | 1 - 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 288b36ea5..233d8dae6 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h \ - bitmap_scale.h bufio.h cs5536.h + bitmap_scale.h bufio.h cs5536.h machine/pci.h include $(srcdir)/conf/mips.mk @@ -27,7 +27,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ - bus/cs5536.c \ + bus/cs5536.c term/serial.c term/terminfo.c term/tparm.c \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) @@ -92,5 +92,35 @@ halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For usb.mod +pkglib_MODULES += 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 +pkglib_MODULES += usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +pkglib_MODULES += ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +pkglib_MODULES += usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +pkglib_MODULES += usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index 218e17d1a..a16fb7a09 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -169,9 +169,11 @@ #ifndef ASM_FILE int EXPORT_FUNC (grub_cs5536_find) (grub_pci_device_t *devp); -grub_uint64_t grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr); -void grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr, - grub_uint64_t val); +grub_uint64_t EXPORT_FUNC (grub_cs5536_read_msr) (grub_pci_device_t dev, + grub_uint32_t addr); +void EXPORT_FUNC (grub_cs5536_write_msr) (grub_pci_device_t dev, + grub_uint32_t addr, + grub_uint64_t val); grub_err_t grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, grub_uint8_t addr, grub_uint8_t *res); grub_err_t EXPORT_FUNC (grub_cs5536_read_spd) (grub_port_t smbbase, diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index 8f3a29d5c..7c816ac8e 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -105,12 +105,12 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) } volatile void * -grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), - grub_addr_t base, grub_size_t size); +EXPORT_FUNC (grub_pci_device_map_range) (grub_pci_device_t dev, + grub_addr_t base, grub_size_t size); void -grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - volatile void *mem, - grub_size_t size __attribute__ ((unused))); +EXPORT_FUNC (grub_pci_device_unmap_range) (grub_pci_device_t dev, + volatile void *mem, + grub_size_t size); #endif #endif /* GRUB_MACHINE_PCI_H */ diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 5d76c5e02..69d5709b6 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include From f78e34d87c779d71e957cc8a0d3ed0505f44b0f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 16 Apr 2010 19:59:51 +0200 Subject: [PATCH 134/503] Initialize power and timing of OHCI. --- bus/usb/ohci.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 6d185bc7f..b385a699a 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include struct grub_ohci_hcca @@ -91,10 +91,18 @@ typedef enum GRUB_OHCI_REG_BULKCURR, GRUB_OHCI_REG_DONEHEAD, GRUB_OHCI_REG_FRAME_INTERVAL, + GRUB_OHCI_REG_PERIODIC_START = 16, GRUB_OHCI_REG_RHUBA = 18, GRUB_OHCI_REG_RHUBPORT = 21 } grub_ohci_reg_t; +#define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 +#define GRUB_OHCI_RHUB_PORT_ALL_POWERED 0x200 + +/* XXX: Is this choice of timings sane? */ +#define GRUB_OHCI_FSMPS 0x2778 +#define GRUB_OHCI_PERIODIC_START 0x257f + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -166,6 +174,11 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) + & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) + | GRUB_OHCI_RHUB_PORT_ALL_POWERED); + /* Backup the frame interval register. */ frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL); @@ -175,8 +188,17 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_dprintf ("ohci", "OHCI reset\n"); /* Restore the frame interval register. */ +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 + + frame_interval = (frame_interval & ~GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK) + | (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT + << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT); grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_PERIODIC_START, + GRUB_OHCI_PERIODIC_START); + /* Setup the HCCA. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); grub_dprintf ("ohci", "OHCI HCCA\n"); From 481695bce082577ca2d56f476be6727b3d543394 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 16 Apr 2010 20:04:44 +0200 Subject: [PATCH 135/503] Adjust OHCI init routines for MIPS and CS5535 --- bus/usb/ohci.c | 90 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index b385a699a..efa2b74e9 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -26,6 +26,7 @@ #include #include #include +#include struct grub_ohci_hcca { @@ -70,6 +71,7 @@ struct grub_ohci { volatile grub_uint32_t *iobase; volatile struct grub_ohci_hcca *hcca; + grub_uint32_t hcca_addr; struct grub_ohci *next; }; @@ -122,51 +124,85 @@ grub_ohci_writereg32 (struct grub_ohci *o, controller. If this is the case, initialize it. */ static int NESTED_FUNC_ATTR grub_ohci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused))) + grub_pci_id_t pciid) { - grub_uint32_t class_code; - grub_uint32_t class; - grub_uint32_t subclass; grub_uint32_t 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 (dev, GRUB_PCI_REG_CLASS); - class_code = grub_pci_read (addr) >> 8; - - interf = class_code & 0xFF; - subclass = (class_code >> 8) & 0xFF; - class = class_code >> 16; - - /* If this is not an OHCI controller, just return. */ - if (class != 0x0c || subclass != 0x03 || interf != 0x10) - return 0; + int cs5536; + grub_uint32_t hcca_addr; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); + grub_dprintf ("ohci", "pciid = %x\n", pciid); + if (pciid == GRUB_CS5536_PCIID) + { + grub_uint64_t basereg; + + cs5536 = 1; + basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE); + if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) + { + /* Shouldn't happen. */ + grub_dprintf ("ohci", "No OHCI address is assigned\n"); + return 0; + } + base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); + basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg); + + } + else + { + grub_uint32_t class_code; + grub_uint32_t class; + grub_uint32_t subclass; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class_code = grub_pci_read (addr) >> 8; + + interf = class_code & 0xFF; + subclass = (class_code >> 8) & 0xFF; + class = class_code >> 16; + + /* If this is not an OHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03 || interf != 0x10) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + base = grub_pci_read (addr); #if 0 - /* Stop if there is no IO space base address defined. */ - if (! (base & 1)) - return 0; + /* Stop if there is no IO space base address defined. */ + if (! (base & 1)) + return 0; #endif + grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n", + class, subclass, interf); + } + /* Allocate memory for the controller and register it. */ o = grub_malloc (sizeof (*o)); if (! o) return 1; - o->iobase = (grub_uint32_t *) base; + o->iobase = grub_pci_device_map_range (dev, base, 0x100); + grub_dprintf ("ohci", "base=%p\n", o->iobase); + + /* FIXME: create proper abstraction for this. */ +#ifdef GRUB_MACHINE_MIPS_YEELOONG + hcca_addr = 0x05000100; +#else /* Reserve memory for the HCCA. */ - o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); - - grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n", - class, subclass, interf, o->iobase); + hcca_addr = (grub_uint32_t) grub_memalign (256, 256); +#endif + o->hcca = grub_pci_device_map_range (dev, hcca_addr, 256); /* Check if the OHCI revision is actually 1.0 as supported. */ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); @@ -200,7 +236,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -216,8 +252,10 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: +#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) grub_free ((void *) o->hcca); +#endif grub_free (o); return 1; From 7e3a6f3b23ab021e66752c278d49dad863bae4b4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 16 Apr 2010 20:05:35 +0200 Subject: [PATCH 136/503] Move few defines to appropriate place --- bus/usb/ohci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index efa2b74e9..69efda435 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -101,6 +101,9 @@ typedef enum #define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 #define GRUB_OHCI_RHUB_PORT_ALL_POWERED 0x200 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 + /* XXX: Is this choice of timings sane? */ #define GRUB_OHCI_FSMPS 0x2778 #define GRUB_OHCI_PERIODIC_START 0x257f @@ -224,9 +227,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_dprintf ("ohci", "OHCI reset\n"); /* Restore the frame interval register. */ -#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 -#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 - frame_interval = (frame_interval & ~GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK) | (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT); From fa2bef48160d1d397e48ed5552ddcd215675865f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 16 Apr 2010 20:41:54 +0200 Subject: [PATCH 137/503] Skip unfunctional controllers --- bus/usb/ohci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 69efda435..de20a1491 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -258,7 +258,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, #endif grub_free (o); - return 1; + return 0; } From 260ddb94173888f802d9de8f50603fa4f3c717ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Apr 2010 16:43:04 +0200 Subject: [PATCH 138/503] create a fat16 image as efi spec requires --- util/grub-mkrescue.in | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index b86be39e0..e7dbb45ff 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -203,21 +203,31 @@ if test -e "${pc_dir}" ; then --embedded-boot ${embed_img}" fi +if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then + efi_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + mkdir -p "${efi_dir}/efi/boot" +else + efi_dir= +fi + # build bootx64.efi if test -e "${efi64_dir}" ; then echo "Generates bootx64.efi" - mkdir -p ${iso9660_dir}/efi/boot - grub-mkimage -d ${efi64_dir}/ -o ${iso9660_dir}/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ + grub-mkimage -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ search iso9660 configfile sh - modules="$(cat ${efi64_dir}/partmap.lst) ${modules}" + modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}" (for i in ${modules} ; do - if [ "x$i" != xkernel.mod ]; then - echo "insmod $i" - fi + echo "insmod $i" done ; \ echo "source /boot/grub/grub.cfg") \ - > ${iso9660_dir}/boot/grub/x86_64-efi/grub.cfg + > "${iso9660_dir}"/boot/grub/x86_64-efi/grub.cfg +fi + +if test x"${efi_dir}" != x; then + mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: + mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ + grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" fi # build iso image From bc05c2cb2c3c77d4bda5900f7cc24c9c00da356f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 24 Apr 2010 21:08:25 +0200 Subject: [PATCH 139/503] Change to xorrisofs. Make message more clear. --- util/grub-mkrescue.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index e7dbb45ff..057577272 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -212,7 +212,7 @@ fi # build bootx64.efi if test -e "${efi64_dir}" ; then - echo "Generates bootx64.efi" + echo "Enabling EFI64 support ..." grub-mkimage -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ search iso9660 configfile sh @@ -231,7 +231,7 @@ if test x"${efi_dir}" != x; then fi # build iso image -grub-mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} +xorrisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} From d31bc9964cd301831055849a21aaa403b297c41b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 01:54:46 +0200 Subject: [PATCH 140/503] migrate kernel.img to elf --- conf/i386-pc.rmk | 5 +- conf/i386-qemu.rmk | 2 +- conf/mips-qemu-mips.rmk | 2 +- conf/mips-yeeloong.rmk | 2 +- conf/sparc64-ieee1275.rmk | 3 +- conf/x86-efi.rmk | 2 +- include/grub/x86_64/efi/boot.h | 0 util/grub-mkrawimage.c | 169 ++++++++++++++++++++++++++++++++- 8 files changed, 172 insertions(+), 13 deletions(-) create mode 100644 include/grub/x86_64/efi/boot.h diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index a5a1b08ea..f2490ba97 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -5,8 +5,7 @@ GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \ - pxeboot.img +pkglib_IMAGES = boot.img cdboot.img diskboot.img lnxboot.img pxeboot.img # For boot.img. boot_img_SOURCES = boot/i386/pc/boot.S @@ -39,6 +38,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00 cdboot_img_FORMAT = binary # For kernel.img. +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/i386/misc.S \ kern/main.c kern/device.c \ @@ -59,7 +59,6 @@ kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) -kernel_img_FORMAT = binary # Utilities. bin_UTILITIES = grub-mkimage diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 664bef12a..923231791 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -19,7 +19,7 @@ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile -pkglib_IMAGES += kernel.img +pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index af5b26bec..2f80ab2e3 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 6a96ddfaf..5ce8ede9d 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -8,7 +8,7 @@ kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h buf include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index f0c9b0db7..8e96599aa 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -5,7 +5,8 @@ COMMON_CFLAGS = -mno-app-regs COMMON_LDFLAGS = -melf64_sparc -mno-relax # Images. -pkglib_IMAGES = boot.img diskboot.img kernel.img +pkglib_IMAGES = boot.img diskboot.img +pkglib_PROGRAMS = kernel.img # For boot.img. boot_img_SOURCES = boot/sparc64/ieee1275/boot.S diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 46957d933..bab561cc4 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -4,7 +4,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile diff --git a/include/grub/x86_64/efi/boot.h b/include/grub/x86_64/efi/boot.h new file mode 100644 index 000000000..e69de29bb diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 20a344d04..dace903a9 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -36,6 +36,7 @@ #include #include #include +#include #define _GNU_SOURCE 1 #include @@ -44,6 +45,8 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define SECTION_ALIGN 1 + #ifdef ENABLE_LZMA #include @@ -97,6 +100,162 @@ compress_kernel (char *kernel_img, size_t kernel_size, #endif /* No lzma compression */ +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +is_text_section (Elf_Shdr *s) +{ + if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (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) +{ + if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC); +} + +/* 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, + grub_size_t *exec_size, grub_size_t *kernel_sz) +{ + 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 = 0; + + /* .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_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address, SECTION_ALIGN); + *exec_size = 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_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address, SECTION_ALIGN); + *kernel_sz = current_address; + return section_addresses; +} + +/* 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_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +static char * +load_image (const char *kernel_path, grub_size_t *exec_size, + grub_size_t *kernel_sz, grub_size_t total_module_size) +{ + char *kernel_img, *out_img; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Addr *section_addresses; + int i; + Elf_Shdr *s; + Elf_Half num_sections; + Elf_Off section_offset; + Elf_Half section_entsize; + grub_size_t kernel_size; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! check_elf_header (e, kernel_size)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host32 (e->e_shoff); + section_entsize = grub_target_to_host16 (e->e_shentsize); + num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) sections + + grub_host_to_target16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_host_to_target32 (s->sh_offset); + + section_addresses = locate_sections (sections, section_entsize, + num_sections, strtab, + exec_size, kernel_sz); + out_img = xmalloc (*kernel_sz + total_module_size); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_data_section (s) || is_text_section (s)) + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + free (kernel_img); + + return out_img; +} + static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, @@ -109,17 +268,15 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ) { char *kernel_img, *core_img; - size_t kernel_size, total_module_size, core_size; + size_t kernel_size, total_module_size, core_size, exec_size; size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0; char *kernel_path; 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); @@ -150,8 +307,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], 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); + kernel_img = load_image (kernel_path, &exec_size, &kernel_size, + total_module_size); if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error (_("prefix is too long")); @@ -237,8 +394,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) = grub_host_to_target32 (total_module_size); #endif +#ifdef GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) = grub_host_to_target32 (kernel_size); +#endif #ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); From e310b81f6cb8c0ad893e08282a49ef42f69d5c9f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:38:12 +0200 Subject: [PATCH 141/503] util/grub-mkrawimage.c working on EFI --- util/grub-mkrawimage.c | 690 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 680 insertions(+), 10 deletions(-) diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index dace903a9..30608a932 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,19 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#ifdef GRUB_MACHINE_EFI +#define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT +#define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) +#else #define SECTION_ALIGN 1 +#define VADDR_OFFSET 0 +#endif + +#if GRUB_TARGET_WORDSIZE == 32 +# define grub_target_to_host(val) grub_target_to_host32(val) +#elif GRUB_TARGET_WORDSIZE == 64 +# define grub_target_to_host(val) grub_target_to_host64(val) +#endif #ifdef ENABLE_LZMA #include @@ -100,13 +113,436 @@ compress_kernel (char *kernel_img, size_t kernel_size, #endif /* No lzma compression */ +#ifdef GRUB_MACHINE_EFI + +/* 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_target_to_host32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + + symtab_size = grub_target_to_host32 (symtab_section->sh_size); + sym_size = grub_target_to_host32 (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host32 (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_target_to_host32 (sym->st_name); + + index = grub_target_to_host16 (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_target_to_host32 (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_target_to_host32 (s->sh_offset) + + i * grub_target_to_host32 (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_target_to_host32 (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_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (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_target_to_host32 (s->sh_link) + * section_entsize)); + target_section_index = grub_target_to_host32 (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_target_to_host32 (s->sh_name), + strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host32 (s->sh_size); + r_size = grub_target_to_host32 (s->sh_entsize); + rtab_offset = grub_target_to_host32 (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; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = get_target_address (e, target_section, offset); + info = grub_target_to_host (r->r_info); + sym_addr = get_symbol_address (e, symtab_section, + ELF_R_SYM (info)); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + r->r_addend : 0; + + 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_host_to_target32 (grub_target_to_host32 (*target) + + addend + 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_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - VADDR_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_host_to_target64 (grub_target_to_host64 (*target) + + addend + 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_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - VADDR_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_host_to_target64 (grub_target_to_host32 (*t32) + + addend + 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; + } + } + } +} + +struct fixup_block_list +{ + struct fixup_block_list *next; + int state; + struct grub_pe32_fixup_block b; +}; + +/* 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 fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + 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_UP (next_address, SECTION_ALIGN) + - 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_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* 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_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Make a .reloc section. */ +static Elf_Addr +make_reloc_section (Elf_Ehdr *e, void **out, + 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 fixup_block_list *lst, *lst0; + Elf_Addr current_address = 0; + + lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); + memset (lst, 0, sizeof (*lst) + 2 * 0x1000); + + 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 (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address); + } +#else + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address); + } +#endif + } + } + + current_address = add_fixup_entry (&lst, 0, 0, 1, current_address); + + { + grub_uint8_t *ptr; + ptr = *out = xmalloc (current_address); + for (lst = lst0; lst; lst = lst->next) + if (lst->state) + { + memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); + ptr += grub_target_to_host32 (lst->b.block_size); + } + if (current_address + *out != ptr) + { + grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, + current_address); + } + } + + return current_address; +} + +#endif + /* Determine if this section is a text section. Return false if this section is not allocated. */ static int is_text_section (Elf_Shdr *s) { +#ifndef GRUB_MACHINE_EFI if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; +#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -117,8 +553,10 @@ is_text_section (Elf_Shdr *s) static int is_data_section (Elf_Shdr *s) { +#ifndef GRUB_MACHINE_EFI if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; +#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -151,7 +589,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address, align); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -159,7 +598,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address, SECTION_ALIGN); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; *exec_size = current_address; /* .data */ @@ -172,7 +612,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address, align); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -180,7 +621,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address, SECTION_ALIGN); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; *kernel_sz = current_address; return section_addresses; } @@ -203,19 +645,25 @@ check_elf_header (Elf_Ehdr *e, size_t size) static char * load_image (const char *kernel_path, grub_size_t *exec_size, - grub_size_t *kernel_sz, grub_size_t total_module_size) + grub_size_t *kernel_sz, grub_size_t *bss_size, + grub_size_t total_module_size, Elf_Addr *start, + void **reloc_section, grub_size_t *reloc_size) { char *kernel_img, *out_img; const char *strtab; Elf_Ehdr *e; Elf_Shdr *sections; Elf_Addr *section_addresses; + Elf_Addr *section_vaddresses; int i; Elf_Shdr *s; Elf_Half num_sections; Elf_Off section_offset; Elf_Half section_entsize; grub_size_t kernel_size; + Elf_Shdr *symtab_section; + + *start = 0; kernel_size = grub_util_get_image_size (kernel_path); kernel_img = xmalloc (kernel_size); @@ -242,15 +690,93 @@ load_image (const char *kernel_path, grub_size_t *exec_size, section_addresses = locate_sections (sections, section_entsize, num_sections, strtab, exec_size, kernel_sz); + +#ifdef GRUB_MACHINE_EFI + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + VADDR_OFFSET; + +#if 0 + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + symtab_section = s; + break; + } + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = relocate_symbols (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections); + if (*start == 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); + + *reloc_size = make_reloc_section (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab); + + } +#else + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; +#endif + out_img = xmalloc (*kernel_sz + total_module_size); for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) if (is_data_section (s) || is_text_section (s)) - memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + section_addresses[i], 0, + grub_host_to_target32 (s->sh_size)); + else + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + } free (kernel_img); return out_img; @@ -274,6 +800,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t offset; struct grub_util_path_list *path_list, *p, *next; struct grub_module_info *modinfo; + grub_size_t bss_size; + Elf_Addr start_address; + void *rel_section; + grub_size_t reloc_size; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -307,8 +837,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = load_image (kernel_path, &exec_size, &kernel_size, - total_module_size); + kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size); if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error (_("prefix is too long")); @@ -456,6 +987,145 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } +#elif defined(GRUB_MACHINE_EFI) + { + void *pe_img; + size_t pe_size; + 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; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + SECTION_ALIGN); + int reloc_addr = ALIGN_UP (header_size + core_size, SECTION_ALIGN); + + pe_size = ALIGN_UP (reloc_addr + reloc_size, SECTION_ALIGN); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + 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_host_to_target16 (GRUB_PE32_MACHINE_I386); +#else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); +#endif + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); + c->characteristics = grub_host_to_target16 (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_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + o->data_base = grub_host_to_target32 (header_size + exec_size); +#endif + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (SECTION_ALIGN); + o->file_alignment = grub_host_to_target32 (SECTION_ALIGN); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + + /* The sections. */ + text_section = (struct grub_pe32_section_table *) (header + 1); + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_ALIGN_64BYTES); + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); + +#if 0 + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); +#endif + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); + + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } #elif defined(GRUB_MACHINE_QEMU) { char *rom_img; From 287c2f24265a5e1ca5c4fe5a6322e9f54b4bb996 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:39:22 +0200 Subject: [PATCH 142/503] Remove efi/grub-mkimage.c --- util/i386/efi/grub-mkimage.c | 1112 ---------------------------------- 1 file changed, 1112 deletions(-) delete mode 100644 util/i386/efi/grub-mkimage.c diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c deleted file mode 100644 index f8c0f152e..000000000 --- a/util/i386/efi/grub-mkimage.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include "progname.h" - -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_le_to_cpu(val) grub_le_to_cpu32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_le_to_cpu(val) grub_le_to_cpu64(val) -#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_image (const char *dir, size_t *size) -{ - char *kernel_image; - char *kernel_path; - - kernel_path = grub_util_get_path (dir, "kernel.img"); - *size = grub_util_get_image_size (kernel_path); - kernel_image = grub_util_read_image (kernel_path); - free (kernel_path); - - 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; - Elf_Addr addend; - - 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)); - - addend = (s->sh_type == grub_cpu_to_le32 (SHT_RELA)) ? - r->r_addend : 0; - - 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 (*target) - + addend + 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 (*target) - + addend + 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 (*target) - + addend + 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_cpu32 (*t32) - + addend + 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_cpu32 (*t32) - + addend + 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; - - memset (&modinfo, 0, sizeof (modinfo)); - - 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; - - memset (&header, 0, sizeof (header)); - - grub_util_info ("adding module %s", p->name); - - mod_size = grub_util_get_image_size (p->name); - header.type = OBJ_TYPE_ELF; - header.size = grub_host_to_target32 (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_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) - { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - 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_DIR64, - 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; - Elf_Shdr *s; - int i; - - /* Get the kernel image and check the format. */ - kernel_image = read_kernel_image (dir, &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); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - - strcpy (kernel_image + offset + GRUB_KERNEL_MACHINE_PREFIX, prefix); - break; - } - - /* 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 `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -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\ -", program_name, 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; - - program_name = "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; -} From 2fa6a5dd4431588f98790e052858f3b851e34bac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:41:51 +0200 Subject: [PATCH 143/503] rename grub-mkrawimage to grub-mkimage --- conf/i386-pc.rmk | 4 ++-- conf/i386-qemu.rmk | 4 ++-- conf/mips.rmk | 4 ++-- conf/sparc64-ieee1275.rmk | 2 +- conf/x86-efi.rmk | 2 +- util/{grub-mkrawimage.c => grub-mkimage.c} | 0 6 files changed, 8 insertions(+), 8 deletions(-) rename util/{grub-mkrawimage.c => grub-mkimage.c} (100%) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index f2490ba97..2dd874e13 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -65,10 +65,10 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 923231791..003f86c33 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -14,10 +14,10 @@ boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LI boot_img_FORMAT = binary bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ util/resolve.c gnulib/progname.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ diff --git a/conf/mips.rmk b/conf/mips.rmk index 4603c219e..c748d3945 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -12,10 +12,10 @@ bin_SCRIPTS = # For grub-mkimage. bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile # For serial.mod. pkglib_MODULES += serial.mod diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 8e96599aa..dd1524df1 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -45,7 +45,7 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname # For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ util/resolve.c gnulib/progname.c # For grub-setup. diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index bab561cc4..8bf0a08d9 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -4,7 +4,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile diff --git a/util/grub-mkrawimage.c b/util/grub-mkimage.c similarity index 100% rename from util/grub-mkrawimage.c rename to util/grub-mkimage.c From 2296410ffbef1c180f3c001dff7abcc39fc6a242 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 22:26:29 +0200 Subject: [PATCH 144/503] initial support for ppc in grub-mkimage (bugs for now) --- conf/common.rmk | 7 ++ conf/i386-pc.rmk | 7 -- conf/i386-qemu.rmk | 6 -- conf/mips.rmk | 7 -- conf/sparc64-ieee1275.rmk | 5 -- conf/x86-efi.rmk | 8 -- include/grub/mips/kernel.h | 2 + include/grub/powerpc/ieee1275/kernel.h | 19 ++++ include/grub/powerpc/kernel.h | 3 - kern/powerpc/ieee1275/startup.S | 6 +- util/elf/grub-mkimage.c | 5 +- util/grub-mkimage.c | 115 +++++++++++++++++++++---- 12 files changed, 133 insertions(+), 57 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..011bb2773 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -21,6 +21,13 @@ grub_mkelfimage_SOURCES = gnulib/progname.c \ util/resolve.c util/elf/grub-mkimage.c_DEPENDENCIES = Makefile +# For grub-mkimage. +bin_UTILITIES += grub-mkimage +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ + util/resolve.c lib/LzmaEnc.c lib/LzFind.c +grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +util/grub-mkimage.c_DEPENDENCIES = Makefile + # For grub-probe. sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 2dd874e13..1e0a3ff58 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -61,15 +61,8 @@ kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 003f86c33..ff263245d 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -13,12 +13,6 @@ boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_M boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) boot_img_FORMAT = binary -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ diff --git a/conf/mips.rmk b/conf/mips.rmk index c748d3945..7d30f55f1 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -10,13 +10,6 @@ kernel_img_HEADERS += cpu/cache.h sbin_SCRIPTS = bin_SCRIPTS = -# For grub-mkimage. -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For serial.mod. pkglib_MODULES += serial.mod serial_mod_SOURCES = term/serial.c diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index dd1524df1..5b71d4cb2 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -41,13 +41,8 @@ kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc kernel_img_FORMAT = binary # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname -# For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c - # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 8bf0a08d9..99a9938ef 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -1,13 +1,5 @@ # -*- makefile -*- -# Utilities. -bin_UTILITIES = grub-mkimage - -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c \ - util/misc.c util/resolve.c -util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile - # Scripts. sbin_SCRIPTS = grub-install diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 8b68f7b6b..172c1dbe2 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -46,6 +46,8 @@ #define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define EM_TARGET EM_MIPS + #ifndef ASM_FILE typedef enum { diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index a76c2a4df..229416243 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -21,8 +21,27 @@ #include +#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define GRUB_KERNEL_MACHINE_PREFIX 0x4 +#define GRUB_KERNEL_MACHINE_DATA_END 0x44 +#define GRUB_KERNEL_MACHINE_LINK_ALIGN 4 + +#define EM_TARGET EM_PPC +#define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 + #ifndef ASM_FILE +typedef enum { + GRUB_PLATFORM_IMAGE_RAW, + GRUB_PLATFORM_IMAGE_ELF +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW +#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF + /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index b4687337f..e4ff65174 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -26,7 +26,4 @@ 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/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 75e1ed852..979f260f8 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end @@ -30,7 +30,7 @@ start: _start: b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: li 2, 0 diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c index 04a19bc4e..f37837c19 100644 --- a/util/elf/grub-mkimage.c +++ b/util/elf/grub-mkimage.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "progname.h" @@ -323,9 +324,9 @@ add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char * if (prefix) { - if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END) + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out); + grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_MACHINE_PREFIX, out); } free (phdrs); diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 30608a932..71376eaee 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -46,6 +46,36 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#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; +}; + #ifdef GRUB_MACHINE_EFI #define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT #define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) @@ -786,11 +816,11 @@ static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format + grub_platform_image_format_t format, #else - int dummy __attribute__ ((unused)) + int dummy __attribute__ ((unused)), #endif - + int note ) { char *kernel_img, *core_img; @@ -1205,7 +1235,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } -#elif defined(GRUB_MACHINE_MIPS) +#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) if (format == GRUB_PLATFORM_IMAGE_ELF) { char *elf_img; @@ -1213,12 +1243,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); program_size = ALIGN_ADDR (core_size); - elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr)); - memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr)); - memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, core_size); + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); ehdr = (void *) elf_img; phdr = (void *) (elf_img + sizeof (*ehdr)); memcpy (ehdr->e_ident, ELFMAG, SELFMAG); @@ -1231,12 +1270,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_ident[EI_VERSION] = EV_CURRENT; ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_MIPS); + ehdr->e_machine = grub_host_to_target16 (EM_TARGET); ehdr->e_version = grub_host_to_target32 (EV_CURRENT); ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (1); + ehdr->e_phnum = grub_host_to_target16 (phnum); /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); @@ -1247,23 +1286,60 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr)); + phdr->p_offset = grub_host_to_target32 (header_size); phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR +#if defined(GRUB_MACHINE_MIPS) + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + kernel_size + total_module_size, 32); +#else + target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; +#endif ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); +#if defined(GRUB_MACHINE_MIPS) ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); +#else + ehdr->e_flags = 0; +#endif phdr->p_filesz = grub_host_to_target32 (core_size); phdr->p_memsz = grub_host_to_target32 (core_size); + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + 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); + + phdr[1].p_type = grub_host_to_target32 (PT_NOTE); + phdr[1].p_flags = grub_host_to_target32 (PF_R); + phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_vaddr = 0; + phdr[1].p_paddr = 0; + phdr[1].p_filesz = grub_host_to_target32 (note_size); + phdr[1].p_memsz = 0; + phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + } + free (core_img); core_img = elf_img; - core_size = program_size + sizeof (*ehdr) + sizeof (*phdr); + core_size = program_size + header_size + footer_size; } #endif @@ -1291,6 +1367,7 @@ static struct option options[] = {"font", required_argument, 0, 'f'}, {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, + {"note", no_argument, 0, 'n'}, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT {"format", required_argument, 0, 'O'}, #endif @@ -1316,6 +1393,7 @@ Make a bootable image of GRUB.\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ + -n, --note add NOTE segment for CHRP Open Firmware\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n" #ifdef GRUB_PLATFORM_IMAGE_DEFAULT "\ @@ -1348,6 +1426,7 @@ main (int argc, char *argv[]) char *font = NULL; char *config = NULL; FILE *fp = stdout; + int note = 0; #ifdef GRUB_PLATFORM_IMAGE_DEFAULT grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; #endif @@ -1358,7 +1437,7 @@ main (int argc, char *argv[]) while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0); if (c == -1) break; @@ -1400,6 +1479,10 @@ main (int argc, char *argv[]) dir = xstrdup (optarg); break; + case 'n': + note = 1; + break; + case 'm': if (memdisk) free (memdisk); @@ -1462,11 +1545,11 @@ main (int argc, char *argv[]) generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format + format, #else - 0 + 0, #endif - ); + note); fclose (fp); From 7576adef7cc18df53688e248fcdabb73aa9cb4da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 23:04:29 +0200 Subject: [PATCH 145/503] Remove grub-mkelfimage --- conf/common.rmk | 7 ------- 1 file changed, 7 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 011bb2773..bab7effb9 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -14,13 +14,6 @@ else grub_mkdevicemap_SOURCES += util/devicemap.c endif -# For grub-mkelfimage. -bin_UTILITIES += grub-mkelfimage -grub_mkelfimage_SOURCES = gnulib/progname.c \ - util/elf/grub-mkimage.c util/misc.c \ - util/resolve.c -util/elf/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-mkimage. bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ From 614be3f11949a6a2e7033e2f2dc4caa3e5a772a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 00:45:21 +0200 Subject: [PATCH 146/503] #if-less grub-mkimage --- include/grub/i386/pc/boot.h | 17 +- include/grub/i386/pc/kernel.h | 24 +- include/grub/i386/pc/memory.h | 6 +- include/grub/i386/qemu/boot.h | 3 - include/grub/i386/qemu/kernel.h | 3 - include/grub/sparc64/ieee1275/boot.h | 4 - include/grub/sparc64/ieee1275/kernel.h | 13 - util/grub-mkimage.c | 1378 +++++++++++++----------- util/grub-mkrescue.in | 2 +- 9 files changed, 765 insertions(+), 685 deletions(-) diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index e88c62b71..09d01caee 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,6 +19,9 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 +#define MACHINE I386_PC +#include + /* The signature for bootloader. */ #define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55 @@ -57,9 +60,6 @@ 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) @@ -68,16 +68,7 @@ #define GRUB_BOOT_MACHINE_PXE_DL 0x7f -#ifndef ASM_FILE - /* This is the blocklist used in the diskboot image. */ -struct grub_boot_blocklist -{ - grub_uint64_t start; - grub_uint16_t len; - grub_uint16_t segment; -} __attribute__ ((packed)); - -#endif /* ! ASM_FILE */ +#define grub_boot_blocklist grub_pc_bios_boot_blocklist #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index e830afae2..77d5c6e5a 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,29 +19,9 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 +#define MACHINE I386_PC -/* 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. */ -#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0) +#include /* Enable LZMA compression */ #define ENABLE_LZMA 1 diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 841b06164..0b4191734 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,6 +29,9 @@ #include +#define MACHINE I386_PC +#include + /* 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) @@ -40,9 +43,6 @@ /* 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 \ diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h index 6fbb57750..5f53eabfb 100644 --- a/include/grub/i386/qemu/boot.h +++ b/include/grub/i386/qemu/boot.h @@ -22,7 +22,4 @@ /* The size of boot.img. */ #define GRUB_BOOT_MACHINE_SIZE (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR) -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR 0x4 - #endif diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index bc0b93d4f..3d22c9d9f 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,9 +19,6 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR 0x8 - /* The offset of GRUB_KERNEL_IMAGE_SIZE. */ #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 9671c6900..bd0a7bf3c 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -50,10 +50,6 @@ #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) -#define GRUB_BOOT_MACHINE_LIST_SIZE 12 - -#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x4400 - #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index a16fb88e7..2948a8d2f 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -42,21 +42,8 @@ #define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, aout" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_AOUT -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT - #include #include diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 71376eaee..af2988a3f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -19,9 +19,6 @@ #include #include -#include -#include -#include #include #include #include @@ -30,6 +27,7 @@ #include #include #include +#include #include #include @@ -44,7 +42,144 @@ #include "progname.h" -#define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#define TARGET_NO_FIELD 0xffffffff +struct image_target_desc +{ + const char *name; + grub_size_t voidp_sizeof; + int bigendian; + enum { + IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, + IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, + IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC + } id; + enum {FORMAT_RAW, FORMAT_AOUT, FORMAT_ELF, FORMAT_PE} format; + enum + { + PLATFORM_FLAGS_NONE = 0, + PLATFORM_FLAGS_LZMA = 1 + } flags; + unsigned prefix; + unsigned data_end; + unsigned raw_size; + unsigned total_module_size; + unsigned kernel_image_size; + unsigned compressed_size; + unsigned link_align; + grub_uint16_t elf_target; + unsigned section_align; + signed vaddr_offset; + unsigned install_dos_part, install_bsd_part; +}; + +struct image_target_desc image_targets[] = + { + {"i386-coreboot", 4, 0, IMAGE_COREBOOT, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + {"i386-pc", 4, 0, IMAGE_I386_PC, FORMAT_RAW, PLATFORM_FLAGS_LZMA, + GRUB_KERNEL_I386_PC_PREFIX, GRUB_KERNEL_I386_PC_DATA_END, + GRUB_KERNEL_I386_PC_RAW_SIZE, GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, GRUB_KERNEL_I386_PC_INSTALL_BSD_PART + }, + {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"i386-qemu", 4, 0, IMAGE_QEMU, FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"powerpc-ieee1275", 4, 1, IMAGE_PPC, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-raw", 8, 1, IMAGE_SPARC64_RAW, + FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-aout", 8, 1, IMAGE_SPARC64_AOUT, + FORMAT_AOUT, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + }; + +#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) + +static inline grub_uint32_t +grub_target_to_host32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu32 (in); + else + return grub_le_to_cpu32 (in); +} + +static inline grub_uint64_t +grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu64 (in); + else + return grub_le_to_cpu64 (in); +} + +static inline grub_uint32_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be32 (in); + else + return grub_cpu_to_le32 (in); +} + +static inline grub_uint16_t +grub_target_to_host16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu16 (in); + else + return grub_le_to_cpu16 (in); +} + +static inline grub_uint16_t +grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be16 (in); + else + return grub_cpu_to_le16 (in); +} #define GRUB_IEEE1275_NOTE_NAME "PowerPC" #define GRUB_IEEE1275_NOTE_TYPE 0x1275 @@ -76,21 +211,8 @@ struct grub_ieee1275_note struct grub_ieee1275_note_desc descriptor; }; -#ifdef GRUB_MACHINE_EFI -#define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT -#define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) -#else -#define SECTION_ALIGN 1 -#define VADDR_OFFSET 0 -#endif +#define grub_target_to_host(val) grub_target_to_host_real(image_target, (val)) -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_target_to_host(val) grub_target_to_host32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_target_to_host(val) grub_target_to_host64(val) -#endif - -#ifdef ENABLE_LZMA #include static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); } @@ -98,8 +220,8 @@ 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) +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size, size_t raw_size) { CLzmaEncProps props; unsigned char out_props[5]; @@ -112,45 +234,47 @@ compress_kernel (char *kernel_img, size_t kernel_size, props.pb = 2; props.numThreads = 1; - if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE) + if (kernel_size < 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); + memcpy (*core_img, kernel_img, 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) + *core_size = kernel_size - raw_size; + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, + (unsigned char *) kernel_img + raw_size, + kernel_size - 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; + *core_size += raw_size; } -#else /* No lzma compression */ - static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) +compress_kernel (struct image_target_desc *image_target, char *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size) { + if (image_target->flags & PLATFORM_FLAGS_LZMA) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size, image_target->raw_size); + return; + } + *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); *core_size = kernel_size; } -#endif /* No lzma compression */ - -#ifdef GRUB_MACHINE_EFI /* 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_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) { Elf_Word symtab_size, sym_size, num_syms; Elf_Off symtab_offset; @@ -209,7 +333,8 @@ relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, /* 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) +get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) { Elf_Sym *sym; @@ -221,7 +346,8 @@ get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) /* Return the address of a modified value. */ static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) +get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) { return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); } @@ -234,7 +360,7 @@ 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) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -283,79 +409,84 @@ relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr addend; offset = grub_target_to_host (r->r_offset); - target = get_target_address (e, target_section, offset); + target = get_target_address (e, target_section, offset, image_target); info = grub_target_to_host (r->r_info); sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info)); + ELF_R_SYM (info), image_target); addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? r->r_addend : 0; - switch (ELF_R_TYPE (info)) - { -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - case R_386_NONE: - break; + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; - case R_386_32: - /* This is absolute. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + 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_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + 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_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr - - target_section_addr - offset - - VADDR_OFFSET); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { -#else + case R_X86_64_NONE: + break; - case R_X86_64_NONE: - break; + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + 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_64: - *target = grub_host_to_target64 (grub_target_to_host64 (*target) - + addend + 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_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_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_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr - - target_section_addr - offset - - VADDR_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_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) 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_host_to_target64 (grub_target_to_host32 (*t32) - + addend + 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; - } + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } } } } @@ -371,7 +502,8 @@ struct fixup_block_list after having written to the file OUT. */ Elf_Addr add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address) + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) { struct grub_pe32_fixup_block *b; @@ -393,7 +525,7 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, size_t index; next_address = current_address + b->block_size; - padding_size = ((ALIGN_UP (next_address, SECTION_ALIGN) + padding_size = ((ALIGN_UP (next_address, image_target->section_align) - next_address) >> 1); index = ((b->block_size - sizeof (*b)) >> 1); @@ -466,7 +598,7 @@ static Elf_Addr make_reloc_section (Elf_Ehdr *e, void **out, Elf_Addr *section_addresses, Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -509,39 +641,44 @@ make_reloc_section (Elf_Ehdr *e, void **out, 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) + if (image_target->voidp_sizeof == 4) { - Elf_Addr addr; + 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 (&lst, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } } -#else - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) + else { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } } -#endif } } - current_address = add_fixup_entry (&lst, 0, 0, 1, current_address); + current_address = add_fixup_entry (&lst, 0, 0, 1, current_address, image_target); { grub_uint8_t *ptr; @@ -562,17 +699,14 @@ make_reloc_section (Elf_Ehdr *e, void **out, return current_address; } -#endif - /* Determine if this section is a text section. Return false if this section is not allocated. */ static int -is_text_section (Elf_Shdr *s) +is_text_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -581,12 +715,11 @@ is_text_section (Elf_Shdr *s) 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) +is_data_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -597,7 +730,8 @@ is_data_section (Elf_Shdr *s) static Elf_Addr * locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, - grub_size_t *exec_size, grub_size_t *kernel_sz) + grub_size_t *exec_size, grub_size_t *kernel_sz, + struct image_target_desc *image_target) { int i; Elf_Addr current_address; @@ -613,14 +747,14 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) + if (is_text_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -628,22 +762,24 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; *exec_size = current_address; /* .data */ for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) + if (is_data_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -651,15 +787,15 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; *kernel_sz = current_address; return section_addresses; } /* Return if the ELF header is valid. */ static int -check_elf_header (Elf_Ehdr *e, size_t size) +check_elf_header (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) { if (size < sizeof (*e) || e->e_ident[EI_MAG0] != ELFMAG0 @@ -677,7 +813,8 @@ static char * load_image (const char *kernel_path, grub_size_t *exec_size, grub_size_t *kernel_sz, grub_size_t *bss_size, grub_size_t total_module_size, Elf_Addr *start, - void **reloc_section, grub_size_t *reloc_size) + void **reloc_section, grub_size_t *reloc_size, + struct image_target_desc *image_target) { char *kernel_img, *out_img; const char *strtab; @@ -700,7 +837,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, grub_util_load_image (kernel_path, kernel_img); e = (Elf_Ehdr *) kernel_img; - if (! check_elf_header (e, kernel_size)) + if (! check_elf_header (e, kernel_size, image_target)) grub_util_error ("invalid ELF header"); section_offset = grub_target_to_host32 (e->e_shoff); @@ -719,85 +856,86 @@ load_image (const char *kernel_path, grub_size_t *exec_size, section_addresses = locate_sections (sections, section_entsize, num_sections, strtab, - exec_size, kernel_sz); + exec_size, kernel_sz, image_target); -#ifdef GRUB_MACHINE_EFI - { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + if (image_target->id == IMAGE_EFI) + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + VADDR_OFFSET; + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; #if 0 - { - Elf_Addr current_address = *kernel_sz; + { + Elf_Addr current_address = *kernel_sz; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); + symtab_section = s; + break; } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = relocate_symbols (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 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, image_target); + + *reloc_size = make_reloc_section (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + + } + else + { + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; } -#else - *bss_size = 0; -#endif - - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) - { - symtab_section = s; - break; - } - - if (! symtab_section) - grub_util_error ("no symbol table"); - - *start = relocate_symbols (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections); - if (*start == 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); - - *reloc_size = make_reloc_section (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab); - - } -#else - *bss_size = 0; - *reloc_size = 0; - *reloc_section = NULL; -#endif out_img = xmalloc (*kernel_sz + total_module_size); for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s) || is_text_section (s)) + if (is_data_section (s, image_target) || is_text_section (s, image_target)) { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) memset (out_img + section_addresses[i], 0, @@ -815,13 +953,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format, -#else - int dummy __attribute__ ((unused)), -#endif - int note -) + struct image_target_desc *image_target, int note) { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size, exec_size; @@ -869,11 +1001,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size); + &reloc_size, image_target); - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); - strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); + strcpy (kernel_img + image_target->prefix, prefix); /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); @@ -946,402 +1078,401 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); - compress_kernel (kernel_img, kernel_size + total_module_size, + compress_kernel (image_target, kernel_img, kernel_size + total_module_size, &core_img, &core_size); grub_util_info ("the core size is 0x%x", core_size); -#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_host_to_target32 (total_module_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_host_to_target32 (kernel_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -#endif + if (image_target->total_module_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + if (image_target->kernel_image_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->kernel_image_size)) + = grub_host_to_target32 (kernel_size); + if (image_target->compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->compressed_size)) + = grub_host_to_target32 (core_size - image_target->raw_size); -#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) /* 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] == '(') + if (image_target->install_dos_part != TARGET_NO_FIELD + && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') { - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) + *((grub_int32_t *) (core_img + image_target->install_dos_part)) = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) + *((grub_int32_t *) (core_img + image_target->install_bsd_part)) = grub_host_to_target32 (-2); } -#endif - -#ifdef GRUB_MACHINE_PCBIOS - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) - grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, - GRUB_MEMORY_MACHINE_UPPER); -#endif - -#if defined(GRUB_MACHINE_PCBIOS) - { - unsigned num; - char *boot_path, *boot_img; - size_t boot_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 size must be %u bytes"), - GRUB_DISK_SECTOR_SIZE); - - boot_img = grub_util_read_image (boot_path); + switch (image_target->id) { - struct grub_boot_blocklist *block; - block = (struct grub_boot_blocklist *) (boot_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*block)); - block->len = grub_host_to_target16 (num); + case IMAGE_I386_PC: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; - /* This is filled elsewhere. Verify it just in case. */ - assert (block->segment - == grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG - + (GRUB_DISK_SECTOR_SIZE >> 4))); - } + if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + grub_util_error (_("core image is too big (%p > %p)"), + GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_MEMORY_I386_PC_UPPER); - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_EFI) - { - void *pe_img; - size_t pe_size; - 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; - static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), - SECTION_ALIGN); - int reloc_addr = ALIGN_UP (header_size + core_size, SECTION_ALIGN); + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (num > 0xffff) + grub_util_error (_("the core image is too big")); - pe_size = ALIGN_UP (reloc_addr + reloc_size, SECTION_ALIGN); - pe_img = xmalloc (reloc_addr + reloc_size); - memset (pe_img, 0, header_size); - memcpy (pe_img + header_size, core_img, core_size); - memcpy (pe_img + reloc_addr, rel_section, reloc_size); - header = pe_img; + 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 size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); - /* The magic. */ - memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); - memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + boot_img = grub_util_read_image (boot_path); - /* The COFF file header. */ - c = &header->coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); -#else - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); -#endif + { + struct grub_pc_bios_boot_blocklist *block; + block = (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len = grub_host_to_target16 (num); - c->num_sections = grub_host_to_target16 (4); - c->time = grub_host_to_target32 (time (0)); - c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); - c->characteristics = grub_host_to_target16 (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); + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } - /* The PE Optional header. */ - o = &header->optional_header; - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); - o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - o->data_base = grub_host_to_target32 (header_size + exec_size); -#endif - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->file_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + void *pe_img; + size_t pe_size; + 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; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + image_target->section_align); + int reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); + pe_size = ALIGN_UP (reloc_addr + reloc_size, image_target->section_align); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + 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 (image_target->voidp_sizeof == 4) + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); + else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof == 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + o = &header->optional_header; + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + if (image_target->voidp_sizeof == 4) + o->data_base = grub_host_to_target32 (header_size + exec_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); - /* The sections. */ - text_section = (struct grub_pe32_section_table *) (header + 1); - strcpy (text_section->name, ".text"); - text_section->virtual_size = grub_cpu_to_le32 (exec_size); - text_section->virtual_address = grub_cpu_to_le32 (header_size); - text_section->raw_data_size = grub_cpu_to_le32 (exec_size); - text_section->raw_data_offset = grub_cpu_to_le32 (header_size); - text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_ALIGN_64BYTES); + /* The sections. */ + text_section = (struct grub_pe32_section_table *) (header + 1); + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_ALIGN_64BYTES); - data_section = text_section + 1; - strcpy (data_section->name, ".data"); - data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); - data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); - data_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); #if 0 - bss_section = data_section + 1; - strcpy (bss_section->name, ".bss"); - bss_section->virtual_size = grub_cpu_to_le32 (bss_size); - bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); - bss_section->raw_data_size = 0; - bss_section->raw_data_offset = 0; - bss_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES - | GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | 0x80); + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); #endif - mods_section = data_section + 1; - strcpy (mods_section->name, "mods"); - mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); - mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); - mods_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); - reloc_section = mods_section + 1; - strcpy (reloc_section->name, ".reloc"); - reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); - reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); - reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); - reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); - reloc_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); - free (core_img); - core_img = pe_img; - core_size = pe_size; - } -#elif defined(GRUB_MACHINE_QEMU) - { - char *rom_img; - size_t rom_size; - char *boot_path, *boot_img; - size_t boot_size; + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; - boot_path = grub_util_get_path (dir, "boot.img"); - boot_size = grub_util_get_image_size (boot_path); - boot_img = grub_util_read_image (boot_path); + boot_path = grub_util_get_path (dir, "boot.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); - /* Rom sizes must be 64k-aligned. */ - rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); + /* Rom sizes must be 64k-aligned. */ + rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); - rom_img = xmalloc (rom_size); - memset (rom_img, 0, rom_size); + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img, core_img, core_size); + memcpy (rom_img, core_img, core_size); - *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); - free (core_img); - core_img = rom_img; - core_size = rom_size; + free (core_img); + core_img = rom_img; + core_size = rom_size; - free (boot_img); - free (boot_path); - } -#elif defined (GRUB_MACHINE_SPARC64) - if (format == GRUB_PLATFORM_IMAGE_AOUT) - { - void *aout_img; - size_t aout_size; - struct grub_aout32_header *aout_head; + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_AOUT: + { + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; - aout_size = core_size + sizeof (*aout_head); - aout_img = xmalloc (aout_size); - aout_head = aout_img; - aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) - | AOUT32_OMAGIC); - aout_head->a_text = grub_host_to_target32 (core_size); - aout_head->a_entry - = grub_host_to_target32 (GRUB_BOOT_MACHINE_IMAGE_ADDRESS); - memcpy (aout_img + sizeof (*aout_head), core_img, core_size); + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS); + memcpy (aout_img + sizeof (*aout_head), core_img, core_size); - free (core_img); - core_img = aout_img; - core_size = aout_size; + free (core_img); + core_img = aout_img; + core_size = aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + 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); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_YEELOONG_ELF: + case IMAGE_PPC: + case IMAGE_COREBOOT: + case IMAGE_I386_IEEE1275: + { + char *elf_img; + size_t program_size; + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); + + program_size = ALIGN_ADDR (core_size); + + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS32; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (image_target->elf_target); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (phnum); + + /* No section headers. */ + ehdr->e_shoff = grub_host_to_target32 (0); + ehdr->e_shentsize = grub_host_to_target16 (0); + ehdr->e_shnum = grub_host_to_target16 (0); + ehdr->e_shstrndx = grub_host_to_target16 (0); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + if (image_target->id == IMAGE_YEELOONG_ELF) + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + + kernel_size + total_module_size, 32); + else + target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags = 0; + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + 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); + + phdr[1].p_type = grub_host_to_target32 (PT_NOTE); + phdr[1].p_flags = grub_host_to_target32 (PF_R); + phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_vaddr = 0; + phdr[1].p_paddr = 0; + phdr[1].p_filesz = grub_host_to_target32 (note_size); + phdr[1].p_memsz = 0; + phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + } + + free (core_img); + core_img = elf_img; + core_size = program_size + header_size + footer_size; + } + break; } - else - { - unsigned int num; - char *boot_path, *boot_img; - size_t boot_size; - - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - num <<= GRUB_DISK_SECTOR_BITS; - - 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); - - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_host_to_target32 (num); - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) - if (format == GRUB_PLATFORM_IMAGE_ELF) - { - char *elf_img; - size_t program_size; - Elf32_Ehdr *ehdr; - Elf32_Phdr *phdr; - grub_uint32_t target_addr; - int header_size, footer_size = 0; - int phnum = 1; - - if (note) - { - phnum++; - footer_size += sizeof (struct grub_ieee1275_note); - } - header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); - - program_size = ALIGN_ADDR (core_size); - - elf_img = xmalloc (program_size + header_size + footer_size); - memset (elf_img, 0, program_size + header_size); - memcpy (elf_img + header_size, core_img, core_size); - ehdr = (void *) elf_img; - phdr = (void *) (elf_img + sizeof (*ehdr)); - memcpy (ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] = ELFCLASS32; -#ifdef GRUB_CPU_MIPSEL - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; -#else - ehdr->e_ident[EI_DATA] = ELFDATA2MSB; -#endif - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; - ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_TARGET); - ehdr->e_version = grub_host_to_target32 (EV_CURRENT); - - ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); - ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (phnum); - - /* No section headers. */ - ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); - ehdr->e_shnum = grub_host_to_target16 (0); - ehdr->e_shstrndx = grub_host_to_target16 (0); - - ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); - - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (header_size); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - -#if defined(GRUB_MACHINE_MIPS) - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); -#else - target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; -#endif - ehdr->e_entry = grub_host_to_target32 (target_addr); - phdr->p_vaddr = grub_host_to_target32 (target_addr); - phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); -#if defined(GRUB_MACHINE_MIPS) - ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER - | EF_MIPS_PIC | EF_MIPS_CPIC); -#else - ehdr->e_flags = 0; -#endif - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); - - if (note) - { - int note_size = sizeof (struct grub_ieee1275_note); - struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) - (elf_img + program_size + header_size); - - 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); - - phdr[1].p_type = grub_host_to_target32 (PT_NOTE); - phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr[1].p_vaddr = 0; - phdr[1].p_paddr = 0; - phdr[1].p_filesz = grub_host_to_target32 (note_size); - phdr[1].p_memsz = 0; - phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); - } - - free (core_img); - core_img = elf_img; - core_size = program_size + header_size + footer_size; - } -#endif grub_util_write_image (core_img, core_size, out); free (kernel_img); @@ -1368,9 +1499,7 @@ static struct option options[] = {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, {"note", no_argument, 0, 'n'}, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT {"format", required_argument, 0, 'O'}, -#endif {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -1383,7 +1512,24 @@ usage (int status) if (status) fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf (_("\ + { + int format_len = 0; + char *formats; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + format_len += strlen (image_targets[i].name) + 2; + ptr = formats = xmalloc (format_len); + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].name); + ptr += strlen (image_targets[i].name); + *ptr++ = ','; + *ptr++ = ' '; + } + ptr[-2] = 0; + + printf (_("\ Usage: %s [OPTION]... [MODULES]\n\ \n\ Make a bootable image of GRUB.\n\ @@ -1394,25 +1540,20 @@ Make a bootable image of GRUB.\n\ -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\ - -o, --output=FILE output a generated image to FILE [default=stdout]\n" -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - "\ - -O, --format=FORMAT generate an image in format [default=%s]\n\ - available formats: %s\n" -#endif - "\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -O, --format=FORMAT generate an image in format\n\ + available formats: %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\ "), -program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT, GRUB_PLATFORM_IMAGE_FORMATS, -#endif -PACKAGE_BUGREPORT); - + program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, + formats, + PACKAGE_BUGREPORT); + free (formats); + } exit (status); } @@ -1427,9 +1568,7 @@ main (int argc, char *argv[]) char *config = NULL; FILE *fp = stdout; int note = 0; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; -#endif + struct image_target_desc *image_target = NULL; set_program_name (argv[0]); @@ -1451,27 +1590,19 @@ main (int argc, char *argv[]) output = xstrdup (optarg); break; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT case 'O': -#ifdef GRUB_PLATFORM_IMAGE_RAW - if (strcmp (optarg, "raw") == 0) - format = GRUB_PLATFORM_IMAGE_RAW; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_ELF - if (strcmp (optarg, "elf") == 0) - format = GRUB_PLATFORM_IMAGE_ELF; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_AOUT - if (strcmp (optarg, "aout") == 0) - format = GRUB_PLATFORM_IMAGE_AOUT; - else -#endif - usage (1); - break; -#endif - + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + if (strcmp (optarg, image_targets[i].name) == 0) + image_target = &image_targets[i]; + if (!image_target) + { + printf ("unknown target %s\n", optarg); + usage (1); + } + break; + } case 'd': if (dir) free (dir); @@ -1534,6 +1665,12 @@ main (int argc, char *argv[]) } } + if (!image_target) + { + printf ("Target not specified.\n"); + usage (1); + } + if (output) { fp = fopen (output, "wb"); @@ -1544,12 +1681,7 @@ main (int argc, char *argv[]) generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format, -#else - 0, -#endif - note); + image_target, note); fclose (fp); diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index aafdfb059..7d553a767 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -171,7 +171,7 @@ fi if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ + grub-mkimage -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img From 94ac7906451fc65323122507c595b790fb2b4644 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 10:56:12 +0200 Subject: [PATCH 147/503] Fix various issues created by previous commits --- Makefile.in | 4 +- boot/i386/qemu/boot.S | 2 +- boot/sparc64/ieee1275/diskboot.S | 11 +- configure.ac | 1 + include/grub/efi/pe32.h | 60 +++++++-- include/grub/i386/pc/boot.h | 1 - include/grub/i386/pc/kernel.h | 2 - include/grub/i386/pc/memory.h | 1 - include/grub/i386/qemu/kernel.h | 9 +- include/grub/offsets.h | 101 ++++++++++++++++ include/grub/powerpc/ieee1275/kernel.h | 18 +-- kern/i386/qemu/startup.S | 2 +- util/grub-mkimage.c | 161 ++++++++++++++++++------- 13 files changed, 285 insertions(+), 88 deletions(-) create mode 100644 include/grub/offsets.h diff --git a/Makefile.in b/Makefile.in index 822a08797..3df8b1b72 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ - -DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\" + -DGRUB_LIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ @@ -287,7 +287,7 @@ build_env.mk: Makefile echo "TARGET_CC=$(TARGET_CC)" ; \ echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \ echo "TARGET_ASFLAGS=$(TARGET_ASFLAGS)" ; \ - echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir) -I$(includedir)" ; \ + echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(libdir) -I$(includedir)" ; \ echo "STRIP=$(STRIP)" ; \ echo "OBJCONV=$(OBJCONV)" ; \ echo "TARGET_MODULE_FORMAT=$(TARGET_MODULE_FORMAT)" ; \ diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S index a93fe3943..51039dd69 100644 --- a/boot/i386/qemu/boot.S +++ b/boot/i386/qemu/boot.S @@ -31,7 +31,7 @@ _start: jmp 1f - . = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 1: diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index a4d4b5bf9..a8fd50d87 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -19,6 +19,7 @@ #include #include +#include .text .align 4 @@ -87,8 +88,8 @@ after_info_block: call console_write mov NOTIFICATION_STRING_LEN, %o3 - GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2) - set GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3 + GET_ABS(firstlist - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2) + set GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS, %l3 bootloop: lduw [%l2 + 0x08], %o0 brz %o0, bootit @@ -115,7 +116,7 @@ bootloop: mov NOTIFICATION_STEP_LEN, %o3 ba bootloop - sub %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2 + sub %l2, GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2 bootit: GET_ABS(prom_close_name, %o0) @@ -127,8 +128,8 @@ bootit: GET_ABS(notification_done, %o2) call console_write mov NOTIFICATION_DONE_LEN, %o3 - sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2 - jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7 + sethi %hi(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o2 + jmpl %o2 + %lo(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o7 mov CIF_REG, %o4 1: ba,a 1b diff --git a/configure.ac b/configure.ac index 4bfc5a2b0..e3453b636 100644 --- a/configure.ac +++ b/configure.ac @@ -148,6 +148,7 @@ case "$target_cpu" in mips) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_MIPS=1" ;; sparc64) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_SPARC64=1" ;; esac +machine_CFLAGS="$machine_CFLAGS -DMACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" CFLAGS="$CFLAGS $machine_CFLAGS" TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS" diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 21b56ae27..9d9edc220 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -99,12 +99,8 @@ struct grub_pe32_optional_header 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; @@ -121,22 +117,66 @@ struct grub_pe32_optional_header 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_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; +}; + +struct grub_pe64_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; + + grub_uint64_t image_base; + + 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; 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; @@ -221,6 +261,8 @@ struct grub_pe32_header struct grub_pe32_optional_header optional_header; }; +#define GRUB_PE32_SIGNATURE_SIZE 4 + struct grub_pe32_fixup_block { grub_uint32_t page_rva; diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index 09d01caee..a4d42ff3c 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,7 +19,6 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 -#define MACHINE I386_PC #include /* The signature for bootloader. */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 77d5c6e5a..f0a9d4fc2 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,8 +19,6 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -#define MACHINE I386_PC - #include /* Enable LZMA compression */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 0b4191734..68f5e8bc9 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,7 +29,6 @@ #include -#define MACHINE I386_PC #include /* The scratch buffer used in real mode code. */ diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index 3d22c9d9f..e29f0aeb2 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,14 +19,7 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x10 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 +#include #ifndef ASM_FILE diff --git a/include/grub/offsets.h b/include/grub/offsets.h new file mode 100644 index 000000000..a0c2f61f9 --- /dev/null +++ b/include/grub/offsets.h @@ -0,0 +1,101 @@ +/* + * 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 OFFSETS_HEADER +#define OFFSETS_HEADER 1 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_INSTALL_DOS_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x14 + +/* The offset of GRUB_INSTALL_BSD_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_PC_PREFIX 0x1c + +/* End of the data section. */ +#define GRUB_KERNEL_I386_PC_DATA_END 0x5c + +/* The size of the first region which won't be compressed. */ +#define GRUB_KERNEL_I386_PC_RAW_SIZE (GRUB_KERNEL_I386_PC_DATA_END + 0x5F0) + +/* The segment where the kernel is loaded. */ +#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 + +/* The upper memory area (starting at 640 kiB). */ +#define GRUB_MEMORY_I386_PC_UPPER 0xa0000 +#define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR 0x4 + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 + +#define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 + +#define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 + +#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 +#define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 + +#ifdef MACHINE +#define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c +#define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) +#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) +#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) + +#define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) +#define GRUB_KERNEL_MACHINE_DATA_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _DATA_END) +#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, MACHINE, _KERNEL_SEG) +#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, MACHINE, _UPPER) +#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _RAW_SIZE) +#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_BSD_PART) +#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_DOS_PART) +#endif + +#ifndef ASM_FILE +struct grub_pc_bios_boot_blocklist +{ + grub_uint64_t start; + grub_uint16_t len; + grub_uint16_t segment; +} __attribute__ ((packed)); +#endif + +#endif diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index 229416243..75d6c62a6 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -20,28 +20,12 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include +#include -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW -#define GRUB_KERNEL_MACHINE_PREFIX 0x4 -#define GRUB_KERNEL_MACHINE_DATA_END 0x44 -#define GRUB_KERNEL_MACHINE_LINK_ALIGN 4 - -#define EM_TARGET EM_PPC #define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/kern/i386/qemu/startup.S b/kern/i386/qemu/startup.S index 7484650b2..dc40cc4a2 100644 --- a/kern/i386/qemu/startup.S +++ b/kern/i386/qemu/startup.S @@ -27,7 +27,7 @@ _start: jmp codestart - . = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 VARIABLE(grub_kernel_image_size) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index af2988a3f..08003a07f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -72,6 +72,7 @@ struct image_target_desc unsigned section_align; signed vaddr_offset; unsigned install_dos_part, install_bsd_part; + grub_uint64_t link_addr; }; struct image_target_desc image_targets[] = @@ -90,8 +91,11 @@ struct image_target_desc image_targets[] = }, {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT) }, {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, @@ -102,8 +106,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0}, {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT) }, {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, @@ -1150,19 +1157,35 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], case IMAGE_EFI: { void *pe_img; + grub_uint8_t *header; size_t pe_size; - 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; static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), - image_target->section_align); - int reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); + int header_size; + int reloc_addr; - pe_size = ALIGN_UP (reloc_addr + reloc_size, image_target->section_align); + if (image_target->voidp_sizeof == 4) + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + else + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + + reloc_addr = ALIGN_UP (header_size + core_size, + image_target->section_align); + + pe_size = ALIGN_UP (reloc_addr + reloc_size, + image_target->section_align); pe_img = xmalloc (reloc_addr + reloc_size); memset (pe_img, 0, header_size); memcpy (pe_img + header_size, core_img, core_size); @@ -1170,11 +1193,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], header = pe_img; /* The magic. */ - memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); - memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); + memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0", + GRUB_PE32_SIGNATURE_SIZE); /* The COFF file header. */ - c = &header->coff_header; + c = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE; if (image_target->voidp_sizeof == 4) c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); else @@ -1182,7 +1206,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], c->num_sections = grub_host_to_target16 (4); c->time = grub_host_to_target32 (time (0)); - c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE | GRUB_PE32_LINE_NUMS_STRIPPED | ((image_target->voidp_sizeof == 4) @@ -1192,33 +1215,74 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], | GRUB_PE32_DEBUG_STRIPPED); /* The PE Optional header. */ - o = &header->optional_header; - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); - o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); if (image_target->voidp_sizeof == 4) - o->data_base = grub_host_to_target32 (header_size + exec_size); - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (image_target->section_align); - o->file_alignment = grub_host_to_target32 (image_target->section_align); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + { + struct grub_pe32_optional_header *o; - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + + o->data_base = grub_host_to_target32 (header_size + exec_size); + + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + } + else + { + struct grub_pe64_optional_header *o; + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + } /* The sections. */ text_section = (struct grub_pe32_section_table *) (header + 1); strcpy (text_section->name, ".text"); @@ -1422,10 +1486,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); if (image_target->id == IMAGE_YEELOONG_ELF) - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); + target_addr = ALIGN_UP (image_target->link_addr + + kernel_size + total_module_size, 32); else - target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; + target_addr = image_target->link_addr; ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); @@ -1534,7 +1598,7 @@ Usage: %s [OPTION]... [MODULES]\n\ \n\ Make a bootable image of GRUB.\n\ \n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ + -d, --directory=DIR use images and modules under DIR [default=%s/@platform@]\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -f, --font=FILE embed FILE as a boot font\n\ @@ -1679,6 +1743,21 @@ main (int argc, char *argv[]) free (output); } + if (!dir) + { + const char *last; + last = strchr (image_target->name, '-'); + if (last) + last = strchr (last + 1, '-'); + if (!last) + last = image_target->name + strlen (image_target->name); + dir = xmalloc (sizeof (GRUB_LIBDIR) + (last - image_target->name)); + memcpy (dir, GRUB_LIBDIR, sizeof (GRUB_LIBDIR) - 1); + memcpy (dir + sizeof (GRUB_LIBDIR) - 1, image_target->name, + last - image_target->name); + *(dir + sizeof (GRUB_LIBDIR) - 1 + (last - image_target->name)) = 0; + } + generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, image_target, note); From 0253aeb7a1ae7c4bc03f4fa4f4c34ff73f4d9ff4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 13:11:43 +0200 Subject: [PATCH 148/503] Unified grub-mkimage achieved --- conf/common.rmk | 1 - conf/i386-pc.rmk | 4 +- include/grub/efi/pe32.h | 9 +- include/grub/kernel.h | 26 +- include/grub/offsets.h | 2 + util/grub-mkimage.c | 767 ++++------------------------------------ util/grub-mkimagexx.c | 741 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 836 insertions(+), 714 deletions(-) create mode 100644 util/grub-mkimagexx.c diff --git a/conf/common.rmk b/conf/common.rmk index bab7effb9..98dca34f9 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -18,7 +18,6 @@ endif bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-probe. diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 1e0a3ff58..f0da94b42 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - COMMON_CFLAGS = -mrtd -mregparm=3 # Images. @@ -58,7 +56,7 @@ kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ machine/pxe.h i386/pit.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS) # Utilities. sbin_UTILITIES = grub-setup diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 9d9edc220..90f9c9f5c 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -199,15 +199,8 @@ struct grub_pe64_optional_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_PE64_MAGIC 0x20b #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 diff --git a/include/grub/kernel.h b/include/grub/kernel.h index bf52ffcb4..f7740b2e3 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -42,19 +42,33 @@ struct grub_module_header /* "gmim" (GRUB Module Info Magic). */ #define GRUB_MODULE_MAGIC 0x676d696d -struct grub_module_info +struct grub_module_info32 { /* 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; + grub_uint32_t offset; /* The size of all modules plus this header. */ - grub_target_size_t size; + grub_uint32_t size; }; +struct grub_module_info64 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + grub_uint32_t padding; + /* The offset of the modules. */ + grub_uint64_t offset; + /* The size of all modules plus this header. */ + grub_uint64_t size; +}; + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +#define grub_module_info grub_module_info64 +#else +#define grub_module_info grub_module_info32 +#endif + extern grub_addr_t grub_arch_modules_addr (void); extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); diff --git a/include/grub/offsets.h b/include/grub/offsets.h index a0c2f61f9..2ba6351ca 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -46,6 +46,8 @@ /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 +#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x8200 + /* The upper memory area (starting at 640 kiB). */ #define GRUB_MEMORY_I386_PC_UPPER 0xa0000 #define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 08003a07f..c9bafdd8b 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -131,6 +131,9 @@ struct image_target_desc image_targets[] = #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) #define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x))) +#define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x))) +#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x))) #define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) #define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) @@ -152,13 +155,13 @@ grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_ return grub_le_to_cpu64 (in); } -static inline grub_uint32_t -grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_host_to_target64_real (struct image_target_desc *image_target, grub_uint64_t in) { - if (image_target->voidp_sizeof == 8) - return grub_target_to_host64_real (image_target, in); + if (image_target->bigendian) + return grub_cpu_to_be64 (in); else - return grub_target_to_host32_real (image_target, in); + return grub_cpu_to_le64 (in); } static inline grub_uint32_t @@ -188,6 +191,24 @@ grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_ return grub_cpu_to_le16 (in); } +static inline grub_uint32_t +grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_host_to_target64_real (image_target, in); + else + return grub_host_to_target32_real (image_target, in); +} + +static inline grub_uint32_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + #define GRUB_IEEE1275_NOTE_NAME "PowerPC" #define GRUB_IEEE1275_NOTE_TYPE 0x1275 @@ -274,230 +295,6 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, *core_size = kernel_size; } - -/* 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, - struct image_target_desc *image_target) -{ - 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_target_to_host32 (symtab_section->sh_link) - * section_entsize)); - strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); - - symtab_size = grub_target_to_host32 (symtab_section->sh_size); - sym_size = grub_target_to_host32 (symtab_section->sh_entsize); - symtab_offset = grub_target_to_host32 (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_target_to_host32 (sym->st_name); - - index = grub_target_to_host16 (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_target_to_host32 (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, - struct image_target_desc *image_target) -{ - Elf_Sym *sym; - - sym = (Elf_Sym *) ((char *) e - + grub_target_to_host32 (s->sh_offset) - + i * grub_target_to_host32 (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, - struct image_target_desc *image_target) -{ - return (Elf_Addr *) ((char *) e + grub_target_to_host32 (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, struct image_target_desc *image_target) -{ - 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_host_to_target32 (SHT_REL)) || - (s->sh_type == grub_host_to_target32 (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_target_to_host32 (s->sh_link) - * section_entsize)); - target_section_index = grub_target_to_host32 (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_target_to_host32 (s->sh_name), - strtab + grub_target_to_host32 (target_section->sh_name)); - - rtab_size = grub_target_to_host32 (s->sh_size); - r_size = grub_target_to_host32 (s->sh_entsize); - rtab_offset = grub_target_to_host32 (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; - Elf_Addr addend; - - offset = grub_target_to_host (r->r_offset); - target = get_target_address (e, target_section, offset, image_target); - info = grub_target_to_host (r->r_info); - sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info), image_target); - - addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? - r->r_addend : 0; - - if (image_target->voidp_sizeof == 4) - switch (ELF_R_TYPE (info)) - { - case R_386_NONE: - break; - - case R_386_32: - /* This is absolute. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + 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_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr - - target_section_addr - offset - - image_target->vaddr_offset); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - else - switch (ELF_R_TYPE (info)) - { - - case R_X86_64_NONE: - break; - - case R_X86_64_64: - *target = grub_host_to_target64 (grub_target_to_host64 (*target) - + addend + 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_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr - - target_section_addr - offset - - image_target->vaddr_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_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - } - } -} - struct fixup_block_list { struct fixup_block_list *next; @@ -505,457 +302,13 @@ struct fixup_block_list struct grub_pe32_fixup_block b; }; -/* 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 fixup_block_list **cblock, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address, - struct image_target_desc *image_target) -{ - struct grub_pe32_fixup_block *b; +#define MKIMAGE_ELF32 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF32 - b = &((*cblock)->b); - - /* First, check if it is necessary to write out the current block. */ - if ((*cblock)->state) - { - 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_UP (next_address, image_target->section_align) - - 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_host_to_target32 (b->page_rva); - b->block_size = grub_host_to_target32 (b->block_size); - (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); - memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); - *cblock = (*cblock)->next; - } - } - - b = &((*cblock)->b); - - if (! flush) - { - grub_uint16_t entry; - size_t index; - - /* If not allocated yet, allocate a block with enough entries. */ - if (! (*cblock)->state) - { - (*cblock)->state = 1; - - /* 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_host_to_target16 (entry); - b->block_size += 2; - } - - return current_address; -} - -/* Make a .reloc section. */ -static Elf_Addr -make_reloc_section (Elf_Ehdr *e, void **out, - Elf_Addr *section_addresses, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, struct image_target_desc *image_target) -{ - Elf_Half i; - Elf_Shdr *s; - struct fixup_block_list *lst, *lst0; - Elf_Addr current_address = 0; - - lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); - memset (lst, 0, sizeof (*lst) + 2 * 0x1000); - - 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 (image_target->voidp_sizeof == 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 (&lst, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address, - image_target); - } - } - else - { - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) - { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address, - image_target); - } - } - } - } - - current_address = add_fixup_entry (&lst, 0, 0, 1, current_address, image_target); - - { - grub_uint8_t *ptr; - ptr = *out = xmalloc (current_address); - for (lst = lst0; lst; lst = lst->next) - if (lst->state) - { - memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); - ptr += grub_target_to_host32 (lst->b.block_size); - } - if (current_address + *out != ptr) - { - grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, - current_address); - } - } - - return current_address; -} - -/* Determine if this section is a text section. Return false if this - section is not allocated. */ -static int -is_text_section (Elf_Shdr *s, struct image_target_desc *image_target) -{ - if (image_target->id != IMAGE_EFI - && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) - return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) - == (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, struct image_target_desc *image_target) -{ - if (image_target->id != IMAGE_EFI - && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) - return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) - == SHF_ALLOC); -} - -/* 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, - grub_size_t *exec_size, grub_size_t *kernel_sz, - struct image_target_desc *image_target) -{ - 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 = 0; - - /* .text */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s, image_target)) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - align) - image_target->vaddr_offset; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); - } - - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - image_target->section_align) - - image_target->vaddr_offset; - *exec_size = current_address; - - /* .data */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s, image_target)) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - align) - - image_target->vaddr_offset; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); - } - - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - image_target->section_align) - image_target->vaddr_offset; - *kernel_sz = current_address; - return section_addresses; -} - -/* Return if the ELF header is valid. */ -static int -check_elf_header (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) -{ - 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_host_to_target32 (EV_CURRENT)) - return 0; - - return 1; -} - -static char * -load_image (const char *kernel_path, grub_size_t *exec_size, - grub_size_t *kernel_sz, grub_size_t *bss_size, - grub_size_t total_module_size, Elf_Addr *start, - void **reloc_section, grub_size_t *reloc_size, - struct image_target_desc *image_target) -{ - char *kernel_img, *out_img; - const char *strtab; - Elf_Ehdr *e; - Elf_Shdr *sections; - Elf_Addr *section_addresses; - Elf_Addr *section_vaddresses; - int i; - Elf_Shdr *s; - Elf_Half num_sections; - Elf_Off section_offset; - Elf_Half section_entsize; - grub_size_t kernel_size; - Elf_Shdr *symtab_section; - - *start = 0; - - kernel_size = grub_util_get_image_size (kernel_path); - kernel_img = xmalloc (kernel_size); - grub_util_load_image (kernel_path, kernel_img); - - e = (Elf_Ehdr *) kernel_img; - if (! check_elf_header (e, kernel_size, image_target)) - grub_util_error ("invalid ELF header"); - - section_offset = grub_target_to_host32 (e->e_shoff); - section_entsize = grub_target_to_host16 (e->e_shentsize); - num_sections = grub_target_to_host16 (e->e_shnum); - - if (kernel_size < section_offset + section_entsize * num_sections) - grub_util_error ("invalid ELF format"); - - sections = (Elf_Shdr *) (kernel_img + section_offset); - - /* Relocate sections then symbols in the virtual address space. */ - s = (Elf_Shdr *) ((char *) sections - + grub_host_to_target16 (e->e_shstrndx) * section_entsize); - strtab = (char *) e + grub_host_to_target32 (s->sh_offset); - - section_addresses = locate_sections (sections, section_entsize, - num_sections, strtab, - exec_size, kernel_sz, image_target); - - if (image_target->id == IMAGE_EFI) - { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; - -#if 0 - { - Elf_Addr current_address = *kernel_sz; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); - } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; - } -#else - *bss_size = 0; -#endif - - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) - { - symtab_section = s; - break; - } - - if (! symtab_section) - grub_util_error ("no symbol table"); - - *start = relocate_symbols (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections, image_target); - if (*start == 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, image_target); - - *reloc_size = make_reloc_section (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab, image_target); - - } - else - { - *bss_size = 0; - *reloc_size = 0; - *reloc_section = NULL; - } - - out_img = xmalloc (*kernel_sz + total_module_size); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s, image_target) || is_text_section (s, image_target)) - { - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - memset (out_img + section_addresses[i], 0, - grub_host_to_target32 (s->sh_size)); - else - memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); - } - free (kernel_img); - - return out_img; -} +#define MKIMAGE_ELF64 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF64 static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], @@ -968,16 +321,18 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; - struct grub_module_info *modinfo; grub_size_t bss_size; - Elf_Addr start_address; + grub_uint64_t start_address; void *rel_section; grub_size_t reloc_size; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); - total_module_size = sizeof (struct grub_module_info); + if (image_target->voidp_sizeof == 8) + total_module_size = sizeof (struct grub_module_info64); + else + total_module_size = sizeof (struct grub_module_info32); if (memdisk_path) { @@ -1006,22 +361,42 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, - total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + if (image_target->voidp_sizeof == 4) + kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, image_target); + else + kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, image_target); if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); strcpy (kernel_img + image_target->prefix, prefix); - /* Fill in the grub_module_info structure. */ - modinfo = (struct grub_module_info *) (kernel_img + kernel_size); - memset (modinfo, 0, sizeof (struct grub_module_info)); - modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info)); - modinfo->size = grub_host_to_target_addr (total_module_size); + if (image_target->voidp_sizeof == 8) + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info64 *modinfo; + modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info64)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info64); + } + else + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info32 *modinfo; + modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info32)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info32); + } - offset = kernel_size + sizeof (struct grub_module_info); for (p = path_list; p; p = p->next) { struct grub_module_header *header; @@ -1119,9 +494,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *boot_path, *boot_img; size_t boot_size; - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_KERNEL_I386_PC_LINK_ADDR + core_size, GRUB_MEMORY_I386_PC_UPPER); num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); @@ -1258,7 +633,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header); - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); o->code_size = grub_host_to_target32 (exec_size); o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); o->bss_size = grub_cpu_to_le32 (bss_size); @@ -1523,7 +898,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr[1].p_type = grub_host_to_target32 (PT_NOTE); phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_align = grub_host_to_target32 (image_target->voidp_sizeof); phdr[1].p_vaddr = 0; phdr[1].p_paddr = 0; phdr[1].p_filesz = grub_host_to_target32 (note_size); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c new file mode 100644 index 000000000..eb0c7a514 --- /dev/null +++ b/util/grub-mkimagexx.c @@ -0,0 +1,741 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 defined(MKIMAGE_ELF32) +# define SUFFIX(x) x ## 32 +# define ELFCLASSXX ELFCLASS32 +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Phdr Elf32_Phdr +# define Elf_Addr Elf32_Addr +# define Elf_Sym Elf32_Sym +# define Elf_Off Elf32_Off +# define Elf_Shdr Elf32_Shdr +# define Elf_Rela Elf32_Rela +# define Elf_Rel Elf32_Rel +# define ELF_R_SYM(val) ELF32_R_SYM(val) +# define ELF_R_TYPE(val) ELF32_R_TYPE(val) +#elif defined(MKIMAGE_ELF64) +# define SUFFIX(x) x ## 64 +# define ELFCLASSXX ELFCLASS64 +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Phdr Elf64_Phdr +# define Elf_Addr Elf64_Addr +# define Elf_Sym Elf64_Sym +# define Elf_Off Elf64_Off +# define Elf_Shdr Elf64_Shdr +# define Elf_Rela Elf64_Rela +# define Elf_Rel Elf64_Rel +# define ELF_R_SYM(val) ELF64_R_SYM(val) +# define ELF_R_TYPE(val) ELF64_R_TYPE(val) +#else +#error "I'm confused" +#endif + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Shdr *symtab_section, Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) +{ + 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_target_to_host32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + + symtab_size = grub_target_to_host32 (symtab_section->sh_size); + sym_size = grub_target_to_host32 (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host32 (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_target_to_host32 (sym->st_name); + + index = grub_target_to_host16 (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_target_to_host32 (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 +SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (s->sh_offset) + + i * grub_target_to_host32 (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host32 (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 +SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + 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_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (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_target_to_host32 (s->sh_link) + * section_entsize)); + target_section_index = grub_target_to_host32 (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_target_to_host32 (s->sh_name), + strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host32 (s->sh_size); + r_size = grub_target_to_host32 (s->sh_entsize); + rtab_offset = grub_target_to_host32 (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; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = SUFFIX (get_target_address) (e, target_section, + offset, image_target); + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + r->r_addend : 0; + + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + 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_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + 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_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_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_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + } + } +} + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +static Elf_Addr +SUFFIX (add_fixup_entry) (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + 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_UP (next_address, image_target->section_align) + - 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_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* 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_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Make a .reloc section. */ +static Elf_Addr +SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, + Elf_Addr *section_addresses, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address = 0; + + lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); + memset (lst, 0, sizeof (*lst) + 2 * 0x1000); + + 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 (image_target->voidp_sizeof == 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 + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } + } + else + { + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } + } + } + } + + current_address = SUFFIX (add_fixup_entry) (&lst, 0, 0, 1, current_address, image_target); + + { + grub_uint8_t *ptr; + ptr = *out = xmalloc (current_address); + for (lst = lst0; lst; lst = lst->next) + if (lst->state) + { + memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); + ptr += grub_target_to_host32 (lst->b.block_size); + } + if (current_address + *out != ptr) + { + grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, + current_address); + } + } + + return current_address; +} + +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (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 +SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC); +} + +/* Return if the ELF header is valid. */ +static int +SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) +{ + 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_ident[EI_CLASS] != ELFCLASSXX + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +/* Locate section addresses by merging code sections and data sections + into .text and .data, respectively. Return the array of section + addresses. */ +static Elf_Addr * +SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, + Elf_Half num_sections, const char *strtab, + grub_size_t *exec_size, grub_size_t *kernel_sz, + struct image_target_desc *image_target) +{ + 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 = 0; + + /* .text */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_text_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *exec_size = current_address; + + /* .data */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; + *kernel_sz = current_address; + return section_addresses; +} + +static char * +SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, + grub_size_t *kernel_sz, grub_size_t *bss_size, + grub_size_t total_module_size, grub_uint64_t *start, + void **reloc_section, grub_size_t *reloc_size, + struct image_target_desc *image_target) +{ + char *kernel_img, *out_img; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Addr *section_addresses; + Elf_Addr *section_vaddresses; + int i; + Elf_Shdr *s; + Elf_Half num_sections; + Elf_Off section_offset; + Elf_Half section_entsize; + grub_size_t kernel_size; + Elf_Shdr *symtab_section; + + *start = 0; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host32 (e->e_shoff); + section_entsize = grub_target_to_host16 (e->e_shentsize); + num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) sections + + grub_host_to_target16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_host_to_target32 (s->sh_offset); + + section_addresses = SUFFIX (locate_sections) (sections, section_entsize, + num_sections, strtab, + exec_size, kernel_sz, image_target); + + if (image_target->id == IMAGE_EFI) + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + +#if 0 + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + symtab_section = s; + break; + } + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = SUFFIX (relocate_symbols) (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + SUFFIX (relocate_addresses) (e, sections, section_addresses, section_entsize, + num_sections, strtab, image_target); + + *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + } + else + { + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; + } + + out_img = xmalloc (*kernel_sz + total_module_size); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target) + || SUFFIX (is_text_section) (s, image_target)) + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + section_addresses[i], 0, + grub_host_to_target32 (s->sh_size)); + else + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + } + free (kernel_img); + + return out_img; +} + + +#undef SUFFIX +#undef ELFCLASSXX +#undef Elf_Ehdr +#undef Elf_Phdr +#undef Elf_Shdr +#undef Elf_Addr +#undef Elf_Sym +#undef Elf_Off +#undef Elf_Rela +#undef Elf_Rel +#undef ELF_R_TYPE +#undef ELF_R_SYM From 962b15b4c19ba248a7e66ebd9f504c901f917361 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 14:42:40 +0200 Subject: [PATCH 149/503] Fill info tables for qemu, sparc and mips --- boot/sparc64/ieee1275/diskboot.S | 2 +- include/grub/mips/kernel.h | 33 ----- include/grub/offsets.h | 31 ++++ include/grub/sparc64/ieee1275/kernel.h | 16 -- kern/mips/startup.S | 23 +-- kern/sparc64/ieee1275/crt0.S | 1 + util/grub-mkimage.c | 198 ++++++++++++++++++------- util/grub-mkimagexx.c | 27 ++-- 8 files changed, 205 insertions(+), 126 deletions(-) diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index a8fd50d87..83dfee098 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -137,7 +137,7 @@ lastlist: .word 0 .word 0 - . = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE) + . = _start + (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE) blocklist_default_start: .word 0 .word 2 diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 172c1dbe2..bc4d43b2b 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -23,41 +23,8 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -#define GRUB_KERNEL_MACHINE_LINK_ALIGN 32 - -#define GRUB_KERNEL_CPU_RAW_SIZE 0x200 -#define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc -#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 - -#define GRUB_KERNEL_CPU_PREFIX GRUB_KERNEL_CPU_RAW_SIZE -#define GRUB_KERNEL_CPU_DATA_END GRUB_KERNEL_CPU_RAW_SIZE + 0x48 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE - -#define GRUB_KERNEL_MACHINE_PREFIX GRUB_KERNEL_CPU_PREFIX -#define GRUB_KERNEL_MACHINE_DATA_END GRUB_KERNEL_CPU_DATA_END -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE - -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - -#define EM_TARGET EM_MIPS - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 2ba6351ca..fc4cd0a46 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -67,14 +67,45 @@ /* End of the data section. */ #define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 +#define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 + +/* End of the data section. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_DATA_END 0x114 + #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 +#define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 +#define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 #define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 + +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN 32 + +#define GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE 0x200 +#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0xc +#define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE 0x10 + +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE +#define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 2948a8d2f..012b5570c 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -24,22 +24,6 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -/* 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_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x14 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x114 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 #ifndef ASM_FILE diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 5e3fb7ad5..876b2df71 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -18,8 +18,9 @@ */ #include -#include +#include #include +#include #define BASE_ADDR 8 @@ -32,13 +33,13 @@ _start: start: bal codestart base: - . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE + . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE compressed_size: .long 0 - . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE + . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE total_module_size: .long 0 - . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE + . = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE kernel_image_size: .long 0 codestart: @@ -105,10 +106,10 @@ argdone: #endif /* Decompress the payload. */ - addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR lui $a1, %hi(compressed) addiu $a1, %lo(compressed) - lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, @@ -134,9 +135,9 @@ reloccont: addiu $t1, %lo(cont) jr $t1 - . = _start + GRUB_KERNEL_CPU_RAW_SIZE + . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE compressed: - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) @@ -146,7 +147,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END #ifdef GRUB_MACHINE_MIPS_YEELOONG VARIABLE (grub_arch_busclock) .long 0 @@ -171,7 +172,7 @@ cont: /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start) - lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) + lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) addu $t2, $t1, $t2 lui $t1, %hi(_end) @@ -181,7 +182,7 @@ cont: nor $t3, $t3, $0 and $t1, $t1, $t3 - lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) + lw $t3, (GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) /* Backward copy. */ add $t1, $t1, $t3 diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S index d5a172296..f0f47416d 100644 --- a/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -18,6 +18,7 @@ */ #include #include +#include .text .align 4 diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index c9bafdd8b..7ba9e595e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -55,7 +55,6 @@ struct image_target_desc IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC } id; - enum {FORMAT_RAW, FORMAT_AOUT, FORMAT_ELF, FORMAT_PE} format; enum { PLATFORM_FLAGS_NONE = 0, @@ -77,56 +76,153 @@ struct image_target_desc struct image_target_desc image_targets[] = { - {"i386-coreboot", 4, 0, IMAGE_COREBOOT, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0 + { + .name = "i386-coreboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 }, - {"i386-pc", 4, 0, IMAGE_I386_PC, FORMAT_RAW, PLATFORM_FLAGS_LZMA, - GRUB_KERNEL_I386_PC_PREFIX, GRUB_KERNEL_I386_PC_DATA_END, - GRUB_KERNEL_I386_PC_RAW_SIZE, GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, - .section_align = 1, - .vaddr_offset = 0, - GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, GRUB_KERNEL_I386_PC_INSTALL_BSD_PART + { + .name = "i386-pc", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC, + .flags = PLATFORM_FLAGS_LZMA, + .prefix = GRUB_KERNEL_I386_PC_PREFIX, + .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, + .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, + .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, - {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, - .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe32_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + { + .name = "i386-efi", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) }, - {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"i386-qemu", 4, 0, IMAGE_QEMU, FORMAT_RAW, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, - .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe64_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + { + .name = "i386-ieee1275", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_IEEE1275, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + { + .name = "i386-qemu", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, + .data_end = GRUB_KERNEL_I386_QEMU_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR + }, + { + .name = "x86_64-efi", + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + { + .name = "mipsel-yeeloong-elf", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_YEELOONG_ELF, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, + .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, + .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN + }, + { + .name = "powerpc-ieee1275", + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_PPC, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + { + .name = "sparc64-ieee1275-raw", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_RAW, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + { + .name = "sparc64-ieee1275-aout", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_AOUT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, - {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"powerpc-ieee1275", 4, 1, IMAGE_PPC, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"sparc64-ieee1275-raw", 8, 1, IMAGE_SPARC64_RAW, - FORMAT_RAW, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"sparc64-ieee1275-aout", 8, 1, IMAGE_SPARC64_AOUT, - FORMAT_AOUT, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, }; #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) @@ -191,8 +287,8 @@ grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_ return grub_cpu_to_le16 (in); } -static inline grub_uint32_t -grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint64_t in) { if (image_target->voidp_sizeof == 8) return grub_host_to_target64_real (image_target, in); @@ -200,8 +296,8 @@ grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint return grub_host_to_target32_real (image_target, in); } -static inline grub_uint32_t -grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint64_t in) { if (image_target->voidp_sizeof == 8) return grub_target_to_host64_real (image_target, in); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index eb0c7a514..abfe56d42 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -67,11 +67,11 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, = (Elf_Shdr *) ((char *) sections + (grub_target_to_host32 (symtab_section->sh_link) * section_entsize)); - strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + strtab = (char *) e + grub_target_to_host (strtab_section->sh_offset); - symtab_size = grub_target_to_host32 (symtab_section->sh_size); - sym_size = grub_target_to_host32 (symtab_section->sh_entsize); - symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); + symtab_size = grub_target_to_host (symtab_section->sh_size); + sym_size = grub_target_to_host (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host (symtab_section->sh_offset); num_syms = symtab_size / sym_size; for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); @@ -482,7 +482,7 @@ SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target) if (image_target->id != IMAGE_EFI && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -495,7 +495,7 @@ SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target) if (image_target->id != IMAGE_EFI && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -543,7 +543,6 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); - if (align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, align) - image_target->vaddr_offset; @@ -551,7 +550,7 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + image_target->vaddr_offset, @@ -576,7 +575,7 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + image_target->vaddr_offset, @@ -616,7 +615,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) grub_util_error ("invalid ELF header"); - section_offset = grub_target_to_host32 (e->e_shoff); + section_offset = grub_target_to_host (e->e_shoff); section_entsize = grub_target_to_host16 (e->e_shentsize); num_sections = grub_target_to_host16 (e->e_shnum); @@ -660,7 +659,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - VADDR_OFFSET; @@ -715,11 +714,11 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) memset (out_img + section_addresses[i], 0, - grub_host_to_target32 (s->sh_size)); + grub_host_to_target_addr (s->sh_size)); else memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); + kernel_img + grub_host_to_target_addr (s->sh_offset), + grub_host_to_target_addr (s->sh_size)); } free (kernel_img); From bb3208158ab37c8a8f28b946b1e804a1442d0c9a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 17:19:15 +0200 Subject: [PATCH 150/503] Fill info for remaining platforms. Make efi image identical to image of previous grub-mkimage --- conf/i386-coreboot.rmk | 4 +- include/grub/efi/pe32.h | 10 ++-- include/grub/i386/efi/kernel.h | 6 --- include/grub/i386/kernel.h | 3 -- include/grub/offsets.h | 21 ++++++++ include/grub/x86_64/efi/kernel.h | 6 --- kern/i386/coreboot/startup.S | 4 +- kern/i386/ieee1275/startup.S | 4 +- util/grub-mkimage.c | 88 ++++++++++++++++++++++++-------- 9 files changed, 101 insertions(+), 45 deletions(-) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 69b8e9a48..11c3abd2a 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -4,8 +4,6 @@ COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/misc.S \ @@ -26,7 +24,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 90f9c9f5c..81a1a5797 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -238,6 +238,7 @@ struct grub_pe32_section_table #define GRUB_PE32_SCN_ALIGN_SHIFT 20 #define GRUB_PE32_SCN_ALIGN_MASK 7 +#define GRUB_PE32_SIGNATURE_SIZE 4 struct grub_pe32_header { @@ -245,17 +246,20 @@ struct grub_pe32_header grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; /* This is always PE\0\0. */ - char signature[4]; + char signature[GRUB_PE32_SIGNATURE_SIZE]; /* The COFF file header. */ struct grub_pe32_coff_header coff_header; +#if GRUB_TARGET_SIZEOF_VOID_P == 8 + /* The Optional header. */ + struct grub_pe64_optional_header optional_header; +#else /* The Optional header. */ struct grub_pe32_optional_header optional_header; +#endif }; -#define GRUB_PE32_SIGNATURE_SIZE 4 - struct grub_pe32_fixup_block { grub_uint32_t page_rva; diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h index c0549f41a..0cb39a215 100644 --- a/include/grub/i386/efi/kernel.h +++ b/include/grub/i386/efi/kernel.h @@ -23,11 +23,5 @@ 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/kernel.h b/include/grub/i386/kernel.h index 5514c8ccf..a0d806929 100644 --- a/include/grub/i386/kernel.h +++ b/include/grub/i386/kernel.h @@ -29,7 +29,4 @@ /* 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/offsets.h b/include/grub/offsets.h index fc4cd0a46..768e4726a 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -93,6 +93,7 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 #define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 #define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 @@ -106,6 +107,26 @@ #define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE #define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_EFI_DATA_END 0x50 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_X86_64_EFI_DATA_END 0x50 + +#define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 +#define GRUB_KERNEL_I386_COREBOOT_DATA_END 0x42 +#define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 + +#define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 +#define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 +#define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h index c0549f41a..0cb39a215 100644 --- a/include/grub/x86_64/efi/kernel.h +++ b/include/grub/x86_64/efi/kernel.h @@ -23,11 +23,5 @@ 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/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index e94950aae..ecdc0b61c 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -42,7 +42,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S index 35258adb6..ad2ef329b 100644 --- a/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -43,7 +43,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -52,7 +52,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 7ba9e595e..25ab5afe4 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -82,8 +82,17 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR }, { .name = "i386-pc", @@ -109,13 +118,21 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_EFI_PREFIX, + .data_end = GRUB_KERNEL_I386_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header) + sizeof (struct grub_pe32_optional_header) + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, }, { .name = "i386-ieee1275", @@ -123,8 +140,17 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_I386_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR }, { .name = "i386-qemu", @@ -150,13 +176,21 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, + .data_end = GRUB_KERNEL_X86_64_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header) + sizeof (struct grub_pe64_optional_header) + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, }, { .name = "mipsel-yeeloong-elf", @@ -184,8 +218,17 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_POWERPC_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR }, { .name = "sparc64-ieee1275-raw", @@ -629,6 +672,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { void *pe_img; grub_uint8_t *header; + void *sections; size_t pe_size; struct grub_pe32_coff_header *c; struct grub_pe32_section_table *text_section, *data_section; @@ -669,7 +713,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], GRUB_PE32_SIGNATURE_SIZE); /* The COFF file header. */ - c = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE; + c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE); if (image_target->voidp_sizeof == 4) c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); else @@ -692,11 +737,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); - o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header); + o = (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); o->bss_size = grub_cpu_to_le32 (bss_size); o->entry_addr = grub_cpu_to_le32 (start_address); o->code_base = grub_cpu_to_le32 (header_size); @@ -720,18 +767,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; } else { struct grub_pe64_optional_header *o; - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); - o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header); + o = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); o->bss_size = grub_cpu_to_le32 (bss_size); o->entry_addr = grub_cpu_to_le32 (start_address); o->code_base = grub_cpu_to_le32 (header_size); @@ -753,9 +803,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; } /* The sections. */ - text_section = (struct grub_pe32_section_table *) (header + 1); + text_section = sections; strcpy (text_section->name, ".text"); text_section->virtual_size = grub_cpu_to_le32 (exec_size); text_section->virtual_address = grub_cpu_to_le32 (header_size); @@ -763,8 +814,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], text_section->raw_data_offset = grub_cpu_to_le32 (header_size); text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_READ); data_section = text_section + 1; strcpy (data_section->name, ".data"); @@ -775,8 +825,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], data_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_WRITE); #if 0 bss_section = data_section + 1; @@ -802,8 +851,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], mods_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_WRITE); reloc_section = mods_section + 1; strcpy (reloc_section->name, ".reloc"); From debaf23f7c1ee4cc70a43a7bebc37667e5a4d6e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 19:11:38 +0200 Subject: [PATCH 151/503] all images binary identical to the ones from trunk --- include/grub/elf.h | 1 + include/grub/i386/kernel.h | 10 ---- include/grub/offsets.h | 16 +++++++ include/grub/powerpc/kernel.h | 7 --- kern/i386/coreboot/init.c | 2 +- kern/ieee1275/init.c | 2 +- util/grub-mkimage.c | 86 ++++++++++++++++++++++++++-------- util/grub-mkimagexx.c | 87 ++++++++++++++++++++--------------- 8 files changed, 137 insertions(+), 74 deletions(-) diff --git a/include/grub/elf.h b/include/grub/elf.h index e54989cde..b9401f241 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -555,6 +555,7 @@ typedef struct #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_GNU_STACK 0x6474e551 /* GCC stack segment */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h index a0d806929..45c7abd72 100644 --- a/include/grub/i386/kernel.h +++ b/include/grub/i386/kernel.h @@ -19,14 +19,4 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 - -#ifdef GRUB_MACHINE_IEEE1275 -#define GRUB_MOD_ALIGN 0x1000 -#else -#define GRUB_MOD_ALIGN 0x1 -#endif - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - #endif diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 768e4726a..a7f252e85 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -127,9 +127,25 @@ #define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 +#define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN 0x1 + +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 + +#define GRUB_KERNEL_POWERPC_IEEE1275_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_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) +#define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_ALIGN) +#define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_GAP) #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index e4ff65174..3fc0b9e23 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -19,11 +19,4 @@ #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 - #endif diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 5f80f28c1..f367269c4 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -144,6 +144,6 @@ grub_arch_modules_addr (void) #ifdef GRUB_MACHINE_QEMU return grub_core_entry_addr + grub_kernel_image_size; #else - return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); #endif } diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index 75f261a71..db9583d8b 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -284,5 +284,5 @@ grub_get_rtc (void) grub_addr_t grub_arch_modules_addr (void) { - return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); } diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 25ab5afe4..cc4a225d4 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -72,6 +72,7 @@ struct image_target_desc signed vaddr_offset; unsigned install_dos_part, install_bsd_part; grub_uint64_t link_addr; + unsigned mod_gap, mod_align; }; struct image_target_desc image_targets[] = @@ -92,7 +93,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, { .name = "i386-pc", @@ -150,7 +155,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, + .link_align = 4, }, { .name = "i386-qemu", @@ -228,7 +237,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, + .elf_target = EM_PPC, + .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, + .link_align = 4 }, { .name = "sparc64-ieee1275-raw", @@ -463,7 +476,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_size_t bss_size; grub_uint64_t start_address; void *rel_section; - grub_size_t reloc_size; + grub_size_t reloc_size, align; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -503,11 +516,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (image_target->voidp_sizeof == 4) kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + &reloc_size, &align, image_target); else kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + &reloc_size, &align, image_target); if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); @@ -961,6 +974,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_uint32_t target_addr; int header_size, footer_size = 0; int phnum = 1; + + if (image_target->id != IMAGE_YEELOONG_ELF) + phnum += 2; if (note) { @@ -994,7 +1010,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_shentsize = grub_host_to_target16 (0); + else + ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf32_Shdr)); ehdr->e_shnum = grub_host_to_target16 (0); ehdr->e_shstrndx = grub_host_to_target16 (0); @@ -1012,14 +1031,44 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (image_target->link_align); + phdr->p_align = grub_host_to_target32 (align > image_target->link_align ? align : image_target->link_align); if (image_target->id == IMAGE_YEELOONG_ELF) ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); else ehdr->e_flags = 0; - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); + if (image_target->id == IMAGE_YEELOONG_ELF) + { + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + } + else + { + grub_uint32_t target_addr_mods; + phdr->p_filesz = grub_host_to_target32 (kernel_size); + phdr->p_memsz = grub_host_to_target32 (kernel_size + bss_size); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_GNU_STACK); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0; + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_filesz = phdr->p_memsz + = grub_host_to_target32 (core_size - kernel_size); + + target_addr_mods = ALIGN_UP (target_addr + kernel_size + bss_size + + image_target->mod_gap, + image_target->mod_align); + phdr->p_vaddr = grub_host_to_target32 (target_addr_mods); + phdr->p_paddr = grub_host_to_target32 (target_addr_mods); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + } if (note) { @@ -1040,14 +1089,15 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); note->descriptor.load_base = grub_host_to_target32 (0x00004000); - phdr[1].p_type = grub_host_to_target32 (PT_NOTE); - phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (image_target->voidp_sizeof); - phdr[1].p_vaddr = 0; - phdr[1].p_paddr = 0; - phdr[1].p_filesz = grub_host_to_target32 (note_size); - phdr[1].p_memsz = 0; - phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + phdr++; + 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 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); } free (core_img); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index abfe56d42..e9fdc7428 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -523,6 +523,7 @@ static Elf_Addr * SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, grub_size_t *exec_size, grub_size_t *kernel_sz, + grub_size_t *all_align, struct image_target_desc *image_target) { int i; @@ -530,11 +531,21 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Addr *section_addresses; Elf_Shdr *s; + *all_align = 1; + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); current_address = 0; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) + && grub_host_to_target32 (s->sh_addralign) > *all_align) + *all_align = grub_host_to_target32 (s->sh_addralign); + + /* .text */ for (i = 0, s = sections; i < num_sections; @@ -546,7 +557,6 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, if (align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, align) - image_target->vaddr_offset; - grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; @@ -589,6 +599,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, grub_size_t *kernel_sz, grub_size_t *bss_size, grub_size_t total_module_size, grub_uint64_t *start, void **reloc_section, grub_size_t *reloc_size, + grub_size_t *align, struct image_target_desc *image_target) { char *kernel_img, *out_img; @@ -631,44 +642,47 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, section_addresses = SUFFIX (locate_sections) (sections, section_entsize, num_sections, strtab, - exec_size, kernel_sz, image_target); + exec_size, kernel_sz, align, + image_target); + + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + + if (image_target->id != IMAGE_EFI) + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + + image_target->vaddr_offset, align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + + image_target->vaddr_offset; + current_address += grub_host_to_target_addr (s->sh_size); + } + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *bss_size = current_address - *kernel_sz; + } + else + *bss_size = 0; if (image_target->id == IMAGE_EFI) { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; - -#if 0 - { - Elf_Addr current_address = *kernel_sz; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target_addr (s->sh_size); - } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; - } -#else - *bss_size = 0; -#endif - symtab_section = NULL; for (i = 0, s = sections; i < num_sections; @@ -699,7 +713,6 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, } else { - *bss_size = 0; *reloc_size = 0; *reloc_section = NULL; } From 8ea6ecb36d0df734d1cef2c0290c114b649c703d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 21:11:16 +0200 Subject: [PATCH 152/503] Some cleanups --- conf/common.rmk | 2 +- conf/i386-pc.rmk | 2 +- include/grub/i386/coreboot/kernel.h | 28 -- include/grub/i386/efi/kernel.h | 27 -- include/grub/i386/ieee1275/kernel.h | 1 - include/grub/i386/kernel.h | 22 -- include/grub/i386/pc/kernel.h | 4 - include/grub/i386/qemu/kernel.h | 4 - include/grub/kernel.h | 4 + include/grub/mips/kernel.h | 34 -- include/grub/mips/qemu-mips/boot.h | 0 include/grub/mips/qemu-mips/kernel.h | 4 - include/grub/mips/yeeloong/boot.h | 0 include/grub/mips/yeeloong/kernel.h | 1 - include/grub/offsets.h | 2 + include/grub/powerpc/ieee1275/kernel.h | 35 -- include/grub/sparc64/ieee1275/kernel.h | 9 - include/grub/sparc64/kernel.h | 30 -- include/grub/types.h | 36 -- include/grub/x86_64/efi/kernel.h | 27 -- include/grub/x86_64/kernel.h | 1 - kern/efi/init.c | 1 - kern/i386/coreboot/init.c | 5 +- kern/i386/coreboot/startup.S | 2 +- kern/i386/ieee1275/startup.S | 1 - kern/ieee1275/cmain.c | 1 - kern/ieee1275/init.c | 3 +- kern/ieee1275/openfw.c | 1 - kern/mips/init.c | 1 - kern/mips/startup.S | 6 +- kern/mips/yeeloong/init.c | 1 - kern/powerpc/ieee1275/startup.S | 2 +- util/elf/grub-mkimage.c | 463 ------------------------- util/grub-mkimagexx.c | 3 + util/i386/pc/grub-setup.c | 7 + util/sparc64/ieee1275/grub-setup.c | 7 + 36 files changed, 34 insertions(+), 743 deletions(-) delete mode 100644 include/grub/i386/coreboot/kernel.h delete mode 100644 include/grub/i386/efi/kernel.h delete mode 100644 include/grub/i386/ieee1275/kernel.h delete mode 100644 include/grub/i386/kernel.h delete mode 100644 include/grub/mips/kernel.h delete mode 100644 include/grub/mips/qemu-mips/boot.h delete mode 100644 include/grub/mips/yeeloong/boot.h delete mode 100644 include/grub/powerpc/ieee1275/kernel.h delete mode 100644 include/grub/sparc64/kernel.h delete mode 100644 include/grub/x86_64/efi/kernel.h delete mode 100644 include/grub/x86_64/kernel.h delete mode 100644 util/elf/grub-mkimage.c diff --git a/conf/common.rmk b/conf/common.rmk index 98dca34f9..f9e7eb194 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -118,7 +118,7 @@ kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ list.h handler.h command.h i18n.h env_private.h libgcc.h ifneq ($(platform), emu) -kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h +kernel_img_HEADERS += machine/memory.h machine/loader.h endif symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index f0da94b42..4c55f28f6 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -53,7 +53,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ term/i386/pc/console.c term/i386/vga_common.c \ symlist.c kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ - machine/pxe.h i386/pit.h + machine/pxe.h i386/pit.h machine/kernel.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS) diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h deleted file mode 100644 index fb60668cc..000000000 --- a/include/grub/i386/coreboot/kernel.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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/efi/kernel.h b/include/grub/i386/efi/kernel.h deleted file mode 100644 index 0cb39a215..000000000 --- a/include/grub/i386/efi/kernel.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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[]; - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h deleted file mode 100644 index dccf8cbe1..000000000 --- a/include/grub/i386/ieee1275/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h deleted file mode 100644 index 45c7abd72..000000000 --- a/include/grub/i386/kernel.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#endif diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index f0a9d4fc2..1de37a5d5 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -41,10 +41,6 @@ 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_uint8_t EXPORT_VAR(grub_boot_drive); diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index e29f0aeb2..0aa2b3d09 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -34,10 +34,6 @@ 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 prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index f7740b2e3..fed875db1 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -90,4 +90,8 @@ void grub_machine_set_prefix (void); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); +#if ! defined (ASM_FILE) && !defined (GRUB_MACHINE_EMU) +extern char grub_prefix[]; +#endif + #endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h deleted file mode 100644 index bc4d43b2b..000000000 --- a/include/grub/mips/kernel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 0x1 -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#ifndef ASM_FILE - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif diff --git a/include/grub/mips/qemu-mips/boot.h b/include/grub/mips/qemu-mips/boot.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/qemu-mips/kernel.h b/include/grub/mips/qemu-mips/kernel.h index dbf74c1b2..230455dbf 100644 --- a/include/grub/mips/qemu-mips/kernel.h +++ b/include/grub/mips/qemu-mips/kernel.h @@ -27,10 +27,6 @@ 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/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 230455dbf..c08405e83 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -20,7 +20,6 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include -#include #ifndef ASM_FILE diff --git a/include/grub/offsets.h b/include/grub/offsets.h index a7f252e85..ae0b2557e 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -136,6 +136,8 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN 0x1 + /* 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. */ diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h deleted file mode 100644 index 75d6c62a6..000000000 --- a/include/grub/powerpc/ieee1275/kernel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 -#include - -#define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 - -#ifndef ASM_FILE - -/* 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/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 012b5570c..5aa50b852 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -19,11 +19,6 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -#define GRUB_MOD_ALIGN 0x2000 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 #ifndef ASM_FILE @@ -37,10 +32,6 @@ 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 prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/sparc64/kernel.h b/include/grub/sparc64/kernel.h deleted file mode 100644 index 9f404b05d..000000000 --- a/include/grub/sparc64/kernel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 0x2000 - -/* 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/types.h b/include/grub/types.h index 9eaafd0c1..6e9461f1d 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -178,21 +178,6 @@ static inline grub_uint64_t grub_swap_bytes64(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)) @@ -206,27 +191,6 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t 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 */ -#if GRUB_TARGET_SIZEOF_VOID_P == 8 -# define grub_host_to_target_addr(x) grub_host_to_target64(x) -#else -# define grub_host_to_target_addr(x) grub_host_to_target32(x) -#endif - #endif /* ! GRUB_TYPES_HEADER */ diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h deleted file mode 100644 index 0cb39a215..000000000 --- a/include/grub/x86_64/efi/kernel.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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[]; - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h deleted file mode 100644 index 25ac57e40..000000000 --- a/include/grub/x86_64/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/kern/efi/init.c b/kern/efi/init.c index a0b4ff779..afd21055d 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -24,7 +24,6 @@ #include #include #include -#include void grub_efi_init (void) diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index f367269c4..08f2cce3a 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -33,8 +32,10 @@ #include #include #include -#include #include +#ifdef GRUB_MACHINE_QEMU +#include +#endif #define GRUB_FLOPPY_REG_DIGITAL_OUTPUT 0x3f2 diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index ecdc0b61c..bdefb69bc 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S index ad2ef329b..c0a08a954 100644 --- a/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c index c1185f82c..cdc8ca051 100644 --- a/kern/ieee1275/cmain.c +++ b/kern/ieee1275/cmain.c @@ -20,7 +20,6 @@ #include #include #include -#include #include int (*grub_ieee1275_entry_fn) (void *); diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index db9583d8b..f79b82776 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -29,10 +29,9 @@ #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) diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index cf9e1a870..5693f3be0 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -21,7 +21,6 @@ #include #include #include -#include #include enum grub_ieee1275_parse_type diff --git a/kern/mips/init.c b/kern/mips/init.c index 5adcedcbb..f220108d4 100644 --- a/kern/mips/init.c +++ b/kern/mips/init.c @@ -18,7 +18,6 @@ #include #include -#include void grub_machine_set_prefix (void) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 876b2df71..1d18131be 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -20,7 +20,7 @@ #include #include #include -#include +#include #define BASE_ADDR 8 @@ -177,8 +177,8 @@ cont: lui $t1, %hi(_end) addiu $t1, %lo(_end) - addiu $t1, (GRUB_MOD_ALIGN-1) - li $t3, (GRUB_MOD_ALIGN-1) + addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) + li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) nor $t3, $t3, $0 and $t1, $t1, $t3 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 6bba27b51..47aa774a0 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -26,7 +26,6 @@ #include #include #include -#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 979f260f8..96d153778 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c deleted file mode 100644 index f37837c19..000000000 --- a/util/elf/grub-mkimage.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU 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 "progname.h" - -#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 *config_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; - size_t config_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); - } - - if (config_path) - { - config_size = ALIGN_UP(grub_util_get_image_size (config_path), 512); - grub_util_info ("the size of memory disk is 0x%x", config_size); - total_module_size += config_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 = 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 = OBJ_TYPE_MEMDISK; - header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (memdisk_path, module_img + offset); - offset += memdisk_size; - } - - if (config_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_CONFIG; - header->size = grub_host_to_target32 (config_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (config_path, module_img + offset); - offset += config_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, char *config_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.img"); - 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, config_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_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_MACHINE_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'}, - {"config", required_argument, 0, 'c'}, - {"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 `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -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\ - -c, --config=FILE embed FILE as boot config\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\ -", program_name, 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; - char *config = NULL; - int chrp = 0; - - set_program_name (argv[0]); - - grub_util_init_nls (); - - while (1) - { - int c = getopt_long (argc, argv, "d:p:m:c: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 'c': - if (config) - free (config); - config = xstrdup (optarg); - - 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, - config); - - fclose (fp); - - return 0; -} diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index e9fdc7428..4a257e329 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -17,6 +17,9 @@ * along with GRUB. If not, see . */ +#undef ELF_R_SYM +#undef ELF_R_TYPE + #if defined(MKIMAGE_ELF32) # define SUFFIX(x) x ## 32 # define ELFCLASSXX ELFCLASS32 diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..f479d5090 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -57,6 +57,13 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_le_to_cpu16(x) +#define grub_target_to_host32(x) grub_le_to_cpu32(x) +#define grub_target_to_host64(x) grub_le_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_le16(x) +#define grub_host_to_target32(x) grub_cpu_to_le32(x) +#define grub_host_to_target64(x) grub_cpu_to_le64(x) + void grub_putchar (int c) { diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index b511a96b2..fbf6ba036 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -76,6 +76,13 @@ #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_be_to_cpu16(x) +#define grub_target_to_host32(x) grub_be_to_cpu32(x) +#define grub_target_to_host64(x) grub_be_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_be16(x) +#define grub_host_to_target32(x) grub_cpu_to_be32(x) +#define grub_host_to_target64(x) grub_cpu_to_be64(x) + /* This is the blocklist used in the diskboot image. */ struct boot_blocklist { From 88d046d01efb74d256ccab953ebe0dbe82b0ee2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 21:27:41 +0200 Subject: [PATCH 153/503] Switch to new grub-mkimage syntax --- util/grub-install.in | 19 +++++++++++-------- util/grub-mkrescue.in | 4 ++-- util/i386/efi/grub-install.in | 2 +- util/ieee1275/grub-install.in | 4 ++-- util/powerpc/ieee1275/grub-mkrescue.in | 4 ++-- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index 142d5792f..8a93ace8c 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -35,11 +35,7 @@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${t localedir=@datadir@/locale grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` -if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` -else - grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` -fi +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -346,16 +342,23 @@ else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi +case "${target_cpu}-${platform}" + i386-pc) mkimage_target=i386-pc ;; + sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; + mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; + *) mkimage_target=i386-coreboot; +esac + if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then - $grub_mkimage ${config_opt} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 # Now perform the installation. $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O ${mkimage_target} --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 else - $grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage -O ${mkimage_target} ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 fi echo "Installation finished. No error reported." diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 7d553a767..a5430534a 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -160,7 +160,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} - grub-mkelfimage -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ + grub-mkimage -O i386-coreboot -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ memdisk tar search iso9660 configfile sh \ ata at_keyboard rm -f ${memdisk_img} @@ -171,7 +171,7 @@ fi if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + grub-mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index cc4d950d2..9b4270ff6 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -213,7 +213,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma # 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 +$grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 1 # Prompt the user to check if the device map is correct. echo "Installation finished. No error reported." diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 363f312db..4d00cc217 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -34,7 +34,7 @@ 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_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -189,7 +189,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma modules="$modules $fs_module $partmap_module $devabstraction_module" # Now perform the installation. -"$grub_mkimage" --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 +"$grub_mkimage" -O ${target_cpu}-ieee1275 --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 if test $update_nvram = yes; then set $ofpathname dummy diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index 0110e799c..16658505b 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -30,7 +30,7 @@ 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_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage # Print the usage. @@ -104,7 +104,7 @@ boot_dir=${iso_dir}/boot/grub mkdir ${iso_dir}/boot mkdir ${boot_dir} core_img=${boot_dir}/grub.img -${grub_mkimage} -n -d ${input_dir}/ -o ${core_img} ${modules} +${grub_mkimage} -O powerpc-ieee1275 -n -d ${input_dir}/ -o ${core_img} ${modules} genisoimage -hfs -part -no-desktop -r -J -o ${output_image} \ -map ${map_file} -hfs-bless ${boot_dir} -chrp-boot -sysid PPC \ ${iso_dir} From 840b61d8f0fc4919fbfdfb0e8495f2c0da81b715 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 10:50:28 +0530 Subject: [PATCH 154/503] reorganized grub-emu sources to suite upcoming automake build system --- {util => bus/emu}/pci.c | 0 {util => bus/usb/emu}/usb.c | 0 conf/any-emu.rmk | 19 ++- conf/common.rmk | 4 +- include/grub/{util => emu}/console.h | 0 include/grub/{util => emu}/getroot.h | 0 include/grub/{util => emu}/hostdisk.h | 0 include/grub/emu/misc.h | 31 ++++ kern/emu/cache.S | 17 +++ {util => kern/emu}/console.c | 2 +- kern/emu/dummy/dl.c | 51 +++++++ {util => kern/emu}/getroot.c | 10 +- {util => kern/emu}/hostdisk.c | 4 +- {util => kern/emu}/hostfs.c | 0 kern/emu/lite.c | 16 +++ util/grub-emu.c => kern/emu/main.c | 42 +++++- kern/emu/misc.c | 199 ++++++++++++++++++++++++++ {util => kern/emu}/time.c | 0 util/grub-probe.c | 5 +- {util => video/emu}/sdl.c | 0 20 files changed, 378 insertions(+), 22 deletions(-) rename {util => bus/emu}/pci.c (100%) rename {util => bus/usb/emu}/usb.c (100%) rename include/grub/{util => emu}/console.h (100%) rename include/grub/{util => emu}/getroot.h (100%) rename include/grub/{util => emu}/hostdisk.h (100%) create mode 100644 include/grub/emu/misc.h create mode 100644 kern/emu/cache.S rename {util => kern/emu}/console.c (99%) create mode 100644 kern/emu/dummy/dl.c rename {util => kern/emu}/getroot.c (98%) rename {util => kern/emu}/hostdisk.c (99%) rename {util => kern/emu}/hostfs.c (100%) create mode 100644 kern/emu/lite.c rename util/grub-emu.c => kern/emu/main.c (91%) create mode 100644 kern/emu/misc.c rename {util => kern/emu}/time.c (100%) rename {util => video/emu}/sdl.c (100%) diff --git a/util/pci.c b/bus/emu/pci.c similarity index 100% rename from util/pci.c rename to bus/emu/pci.c diff --git a/util/usb.c b/bus/usb/emu/usb.c similarity index 100% rename from util/usb.c rename to bus/usb/emu/usb.c diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index d1e5754dc..5f6798d79 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -10,11 +10,11 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ \ - util/console.c util/grub-emu.c util/misc.c \ - util/hostdisk.c util/getroot.c util/mm.c util/time.c \ + kern/emu/misc.c kern/emu/getroot.c kern/emu/time.c \ + kern/emu/hostdisk.c kern/emu/hostfs.c kern/emu/console.c \ \ - gnulib/progname.c util/hostfs.c disk/host.c -kernel_img_HEADERS += datetime.h util/misc.h + gnulib/progname.c disk/host.c +kernel_img_HEADERS += datetime.h emu/misc.h kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes @@ -49,7 +49,7 @@ ifeq ($(enable_grub_emu_usb), yes) kernel_img_HEADERS += libusb.h pkglib_MODULES += libusb.mod -libusb_mod_SOURCES = util/usb.c +libusb_mod_SOURCES = bus/usb/emu/usb.c libusb_mod_CFLAGS = libusb_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -76,7 +76,7 @@ endif ifeq ($(enable_grub_emu_sdl), yes) pkglib_MODULES += sdl.mod -sdl_mod_SOURCES = util/sdl.c +sdl_mod_SOURCES = video/emu/sdl.c sdl_mod_CFLAGS = sdl_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBSDL) @@ -106,8 +106,13 @@ ifneq ($(TARGET_NO_MODULES), yes) grub-emu: $(pkglib_PROGRAMS) $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) else + +pkglib_MODULES += emu.mod +emu_mod_SOURCES = kern/emu/main.c +emu_mod_CFLAGS = -I$(srcdir)/gnulib + grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) - $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) + $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) endif GRUB_EMU=grub-emu diff --git a/conf/common.rmk b/conf/common.rmk index 8df232a0b..6267d7818 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -25,7 +25,7 @@ util/elf/grub-mkimage.c_DEPENDENCIES = Makefile sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ - util/hostdisk.c util/misc.c util/getroot.c util/mm.c \ + kern/emu/hostdisk.c util/misc.c kern/emu/getroot.c util/mm.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ kern/parser.c kern/partition.c kern/file.c kern/list.c \ \ @@ -60,7 +60,7 @@ grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h -grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ +grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ util/misc.c util/mm.c \ kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ disk/host.c disk/loopback.c kern/list.c kern/command.c \ diff --git a/include/grub/util/console.h b/include/grub/emu/console.h similarity index 100% rename from include/grub/util/console.h rename to include/grub/emu/console.h diff --git a/include/grub/util/getroot.h b/include/grub/emu/getroot.h similarity index 100% rename from include/grub/util/getroot.h rename to include/grub/emu/getroot.h diff --git a/include/grub/util/hostdisk.h b/include/grub/emu/hostdisk.h similarity index 100% rename from include/grub/util/hostdisk.h rename to include/grub/emu/hostdisk.h diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h new file mode 100644 index 000000000..e62aeba08 --- /dev/null +++ b/include/grub/emu/misc.h @@ -0,0 +1,31 @@ +#ifndef GRUB_EMU_MISC_H +#define GRUB_EMU_MISC_H 1 + +#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 int verbosity; +extern const char *program_name; + +void grub_init_all (void); +void grub_fini_all (void); + +void * EXPORT_FUNC(xmalloc) (grub_size_t size); +void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size); +char * EXPORT_FUNC(xstrdup) (const char *str); +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); + +void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); + +#endif /* GRUB_EMU_MISC_H */ diff --git a/kern/emu/cache.S b/kern/emu/cache.S new file mode 100644 index 000000000..087b2b495 --- /dev/null +++ b/kern/emu/cache.S @@ -0,0 +1,17 @@ +#ifndef GRUB_MACHINE_EMU +#error "This source is only meant for grub-emu platform" +#endif + +#if GRUB_CPU_I386 +#elif GRUB_CPU_X86_64 +#elif GRUB_CPU_SPARC64 +#include "../sparc64/cache.S" +#elif GRUB_CPU_MIPS +#include "../mips/cache.S" +#elif GRUB_CPU_MIPSEL +#include "../mips/cache.S" +#elif GRUB_CPU_POWERPC +#include "../powerpc/cache.S" +#else +#error "No target cpu type is defined" +#endif diff --git a/util/console.c b/kern/emu/console.c similarity index 99% rename from util/console.c rename to kern/emu/console.c index 382fd7f89..f7fbc899a 100644 --- a/util/console.c +++ b/kern/emu/console.c @@ -27,7 +27,7 @@ # define A_STANDOUT 0 #endif /* ! A_STANDOUT */ -#include +#include #include #include diff --git a/kern/emu/dummy/dl.c b/kern/emu/dummy/dl.c new file mode 100644 index 000000000..8e9fabfc2 --- /dev/null +++ b/kern/emu/dummy/dl.c @@ -0,0 +1,51 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_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; +} + +/* int */ +/* grub_dl_ref (grub_dl_t mod) */ +/* { */ +/* (void) mod; */ +/* return 0; */ +/* } */ + +/* int */ +/* grub_dl_unref (grub_dl_t mod) */ +/* { */ +/* (void) mod; */ +/* return 0; */ +/* } */ diff --git a/util/getroot.c b/kern/emu/getroot.c similarity index 98% rename from util/getroot.c rename to kern/emu/getroot.c index 94eadc5e1..91799aa8f 100644 --- a/util/getroot.c +++ b/kern/emu/getroot.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #ifdef __CYGWIN__ # include @@ -36,9 +38,11 @@ #include #endif -#include -#include -#include +#include +#include +#include +#include +#include static void strip_extra_slashes (char *dir) diff --git a/util/hostdisk.c b/kern/emu/hostdisk.c similarity index 99% rename from util/hostdisk.c rename to kern/emu/hostdisk.c index 8be487461..983f101ae 100644 --- a/util/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/util/hostfs.c b/kern/emu/hostfs.c similarity index 100% rename from util/hostfs.c rename to kern/emu/hostfs.c diff --git a/kern/emu/lite.c b/kern/emu/lite.c new file mode 100644 index 000000000..1f06e39dc --- /dev/null +++ b/kern/emu/lite.c @@ -0,0 +1,16 @@ +#include +#include + +/* grub-emu-lite supports dynamic module loading, so it won't have any + embedded modules. */ +void +grub_init_all(void) +{ + return; +} + +void +grub_fini_all(void) +{ + return; +} diff --git a/util/grub-emu.c b/kern/emu/main.c similarity index 91% rename from util/grub-emu.c rename to kern/emu/main.c index 8660f0aa0..978919f2a 100644 --- a/util/grub-emu.c +++ b/kern/emu/main.c @@ -16,7 +16,10 @@ * along with GRUB. If not, see . */ +#include +#include #include +#include #include #include #include @@ -27,13 +30,13 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include -#include +#include #include #include #include @@ -261,3 +264,32 @@ main (int argc, char *argv[]) return 0; } + +#ifdef __MINGW32__ + +void +grub_millisleep (grub_uint32_t ms) +{ + Sleep (ms); +} + +#else + +void +grub_millisleep (grub_uint32_t ms) +{ + struct timespec ts; + + ts.tv_sec = ms / 1000; + ts.tv_nsec = (ms % 1000) * 1000000; + nanosleep (&ts, NULL); +} + +#endif + +#if GRUB_NO_MODULES +void +grub_register_exported_symbols (void) +{ +} +#endif diff --git a/kern/emu/misc.c b/kern/emu/misc.c new file mode 100644 index 000000000..d8dfc938d --- /dev/null +++ b/kern/emu/misc.c @@ -0,0 +1,199 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int verbosity; + +void +grub_util_warn (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, _("%s: warn:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + fflush (stderr); +} + +void +grub_util_info (const char *fmt, ...) +{ + if (verbosity > 0) + { + va_list ap; + + fprintf (stderr, _("%s: info:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + fflush (stderr); + } +} + +void +grub_util_error (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, _("%s: error:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + exit (1); +} + +void * +grub_malloc (grub_size_t size) +{ + return malloc (size); +} + +void * +grub_zalloc (grub_size_t size) +{ + void *ret; + + ret = malloc (size); + memset (ret, 0, size); + return ret; +} + +void +grub_free (void *ptr) +{ + free (ptr); +} + +void * +grub_realloc (void *ptr, grub_size_t size) +{ + return realloc (ptr, size); +} + +void * +grub_memalign (grub_size_t align, grub_size_t size) +{ + void *p; + +#if defined(HAVE_POSIX_MEMALIGN) + if (align < sizeof (void *)) + align = sizeof (void *); + + else if (align % sizeof (void *)) + grub_fatal ("bad alignment"); + + if (posix_memalign (&p, align, size) != 0) + p = 0; +#elif defined(HAVE_MEMALIGN) + p = memalign (align, size); +#else + (void) align; + (void) size; + grub_fatal ("grub_memalign is not supported"); +#endif + + if (! p) + grub_fatal ("out of memory"); + + return p; +} + +void * +xmalloc (grub_size_t size) +{ + void *p; + + p = grub_malloc (size); + if (! p) + grub_fatal ("out of memory"); + + return p; +} + +void * +xrealloc (void *ptr, grub_size_t size) +{ + ptr = grub_realloc (ptr, size); + if (! ptr) + grub_fatal ("out of memory"); + + return ptr; +} + +char * +xstrdup (const char *str) +{ + size_t len; + char *newstr; + + len = grub_strlen (str); + newstr = (char *) xmalloc (len + 1); + grub_memcpy (newstr, str, len + 1); + + return newstr; +} + +char * +xasprintf (const char *fmt, ...) +{ + va_list ap; + char *result; + + va_start (ap, fmt); + if (vasprintf (&result, fmt, ap) < 0) + { + if (errno == ENOMEM) + grub_util_error ("out of memory"); + return NULL; + } + + return result; +} + +void +grub_exit (void) +{ + exit (1); +} + +grub_uint64_t +grub_get_time_ms (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + +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)); +} diff --git a/util/time.c b/kern/emu/time.c similarity index 100% rename from util/time.c rename to kern/emu/time.c diff --git a/util/grub-probe.c b/util/grub-probe.c index bb41480e2..1b2606dc7 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -26,8 +27,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/util/sdl.c b/video/emu/sdl.c similarity index 100% rename from util/sdl.c rename to video/emu/sdl.c From 4c7085f82be6f018c895b9fd871ff8eed1d94be3 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 13:57:14 +0530 Subject: [PATCH 155/503] added support for --enable-grub-emu-modules build --- conf/any-emu.rmk | 18 +++++++--------- include/grub/dl.h | 15 ------------- kern/dl.c | 8 +++++-- kern/emu/cache.S | 17 --------------- kern/emu/dummy/dl.c | 51 --------------------------------------------- kern/emu/lite.c | 16 -------------- kern/emu/main.c | 1 + util/misc.c | 14 +++++++++++++ 8 files changed, 28 insertions(+), 112 deletions(-) delete mode 100644 kern/emu/cache.S delete mode 100644 kern/emu/dummy/dl.c delete mode 100644 kern/emu/lite.c diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 5f6798d79..ffaabcd2f 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -9,10 +9,11 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ - \ - kern/emu/misc.c kern/emu/getroot.c kern/emu/time.c \ - kern/emu/hostdisk.c kern/emu/hostfs.c kern/emu/console.c \ - \ + \ + kern/emu/main.c kern/emu/misc.c kern/emu/getroot.c \ + kern/emu/time.c kern/emu/hostdisk.c kern/emu/hostfs.c \ + kern/emu/console.c \ + \ gnulib/progname.c disk/host.c kernel_img_HEADERS += datetime.h emu/misc.h kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib @@ -85,7 +86,7 @@ endif ifeq ($(enable_grub_emu_pci), yes) pkglib_MODULES += pci.mod -pci_mod_SOURCES = util/pci.c commands/lspci.c +pci_mod_SOURCES = bus/emu/pci.c commands/lspci.c pci_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBPCIACCESS) kernel_img_HEADERS += libpciaccess.h @@ -104,13 +105,8 @@ DISTCLEANFILES += grub_emu_init.c CLEANFILES += grub-emu ifneq ($(TARGET_NO_MODULES), yes) grub-emu: $(pkglib_PROGRAMS) - $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) + $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) else - -pkglib_MODULES += emu.mod -emu_mod_SOURCES = kern/emu/main.c -emu_mod_CFLAGS = -I$(srcdir)/gnulib - grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) endif diff --git a/include/grub/dl.h b/include/grub/dl.h index cfb7c2f99..cf5da7fd5 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -96,23 +96,8 @@ void grub_dl_unload_all (void); #else #define GRUB_NO_MODULES 0 #endif -#if GRUB_NO_MODULES -static inline int -grub_dl_ref (grub_dl_t mod) -{ - (void) mod; - return 0; -} -static inline int -grub_dl_unref (grub_dl_t mod) -{ - (void) mod; - return 0; -} -#else int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); -#endif 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 grub_dl_register_symbol (const char *name, void *addr, diff --git a/kern/dl.c b/kern/dl.c index 19ee13243..c6a038cfa 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -469,12 +469,14 @@ grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) return GRUB_ERR_NONE; } -#if !GRUB_NO_MODULES int grub_dl_ref (grub_dl_t mod) { grub_dl_dep_t dep; + if (!mod) + return 0; + for (dep = mod->dep; dep; dep = dep->next) grub_dl_ref (dep->mod); @@ -486,12 +488,14 @@ grub_dl_unref (grub_dl_t mod) { grub_dl_dep_t dep; + if (!mod) + return 0; + for (dep = mod->dep; dep; dep = dep->next) grub_dl_unref (dep->mod); return --mod->ref_count; } -#endif static void grub_dl_flush_cache (grub_dl_t mod) diff --git a/kern/emu/cache.S b/kern/emu/cache.S deleted file mode 100644 index 087b2b495..000000000 --- a/kern/emu/cache.S +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef GRUB_MACHINE_EMU -#error "This source is only meant for grub-emu platform" -#endif - -#if GRUB_CPU_I386 -#elif GRUB_CPU_X86_64 -#elif GRUB_CPU_SPARC64 -#include "../sparc64/cache.S" -#elif GRUB_CPU_MIPS -#include "../mips/cache.S" -#elif GRUB_CPU_MIPSEL -#include "../mips/cache.S" -#elif GRUB_CPU_POWERPC -#include "../powerpc/cache.S" -#else -#error "No target cpu type is defined" -#endif diff --git a/kern/emu/dummy/dl.c b/kern/emu/dummy/dl.c deleted file mode 100644 index 8e9fabfc2..000000000 --- a/kern/emu/dummy/dl.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU 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_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; -} - -/* int */ -/* grub_dl_ref (grub_dl_t mod) */ -/* { */ -/* (void) mod; */ -/* return 0; */ -/* } */ - -/* int */ -/* grub_dl_unref (grub_dl_t mod) */ -/* { */ -/* (void) mod; */ -/* return 0; */ -/* } */ diff --git a/kern/emu/lite.c b/kern/emu/lite.c deleted file mode 100644 index 1f06e39dc..000000000 --- a/kern/emu/lite.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -/* grub-emu-lite supports dynamic module loading, so it won't have any - embedded modules. */ -void -grub_init_all(void) -{ - return; -} - -void -grub_fini_all(void) -{ - return; -} diff --git a/kern/emu/main.c b/kern/emu/main.c index 978919f2a..c9b1d6595 100644 --- a/kern/emu/main.c +++ b/kern/emu/main.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/util/misc.c b/util/misc.c index 17fa6d5e4..c413352e7 100644 --- a/util/misc.c +++ b/util/misc.c @@ -564,3 +564,17 @@ grub_util_init_nls (void) #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } #endif + +int +grub_dl_ref (grub_dl_t mod) +{ + (void) mod; + return 0; +} + +int +grub_dl_unref (grub_dl_t mod) +{ + (void) mod; + return 0; +} From 13ac43057bcac4644bc50e572c804c7e04470a49 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 11:08:53 +0200 Subject: [PATCH 156/503] use uuids on efi --- kern/efi/init.c | 76 +++++++++++++++++++++++++++---------------- util/grub-mkrescue.in | 24 +++++++++++--- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/kern/efi/init.c b/kern/efi/init.c index afd21055d..b79084a6a 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -24,6 +24,7 @@ #include #include #include +#include void grub_efi_init (void) @@ -41,39 +42,58 @@ grub_efi_init (void) void grub_efi_set_prefix (void) { - grub_efi_loaded_image_t *image; + grub_efi_loaded_image_t *image = NULL; + char *device = NULL; + char *path = NULL; - image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (image) + { + char *pptr = NULL; + if (grub_prefix[0] == '(') + { + pptr = grub_strrchr (grub_prefix, ')'); + if (pptr) + { + device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); + pptr++; + } + } + if (!pptr) + pptr = grub_prefix; + if (pptr[0]) + path = grub_strdup (pptr); + } + + if (!device || !path) + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (image && !device) + device = grub_efidisk_get_device_name (image->device_handle); + + if (image && !path) { - char *device; - char *file; + char *p; - device = grub_efidisk_get_device_name (image->device_handle); - file = grub_efi_get_filename (image->file_path); + path = 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_xasprintf ("(%s)%s", device, file); - if (prefix) - { - - grub_env_set ("prefix", prefix); - grub_free (prefix); - } - } - - grub_free (device); - grub_free (file); + /* Get the directory. */ + p = grub_strrchr (path, '/'); + if (p) + *p = '\0'; } + + if (device && path) + { + char *prefix; + + prefix = grub_xasprintf ("(%s)%s", device, path); + if (prefix) + { + grub_env_set ("prefix", prefix); + grub_free (prefix); + } + } + + grub_free (device); + grub_free (path); } void diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index cf791d108..0265f9b81 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -150,14 +150,16 @@ else esac fi +# obtain date-based UUID +iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) +grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" + # build coreboot core.img if test -e "${coreboot_dir}" ; then echo "Enabling coreboot support ..." memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${memdisk_dir}/boot/grub - # obtain date-based UUID - iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) modules="$(cat ${coreboot_dir}/partmap.lst) ${modules}" cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg @@ -176,7 +178,6 @@ EOF memdisk tar search iso9660 configfile sh \ ata at_keyboard rm -f ${memdisk_img} - grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" fi # build BIOS core.img @@ -213,8 +214,21 @@ fi # build bootx64.efi if test -e "${efi64_dir}" ; then echo "Enabling EFI64 support ..." - grub-mkimage -O x86_64-efi -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ - search iso9660 configfile sh + memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` + memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + mkdir -p ${memdisk_dir}/boot/grub + + cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg +search --fs-uuid --set ${iso_uuid} +set prefix=(\${root})/boot/grub/${target_cpu}-efi +EOF + + tar -C ${memdisk_dir} -cf ${memdisk_img} boot + rm -rf ${memdisk_dir} + + grub-mkimage -O x86_64-efi -d "${efi64_dir}" -m "${memdisk_img}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix='(memdisk)/boot/grub' \ + search iso9660 configfile sh memdisk tar + rm -f ${memdisk_img} modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}" (for i in ${modules} ; do From ff6bea78b442acb7e2304d9ae7c78a94237422e2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 13:22:38 +0200 Subject: [PATCH 157/503] Enable pathspecs --- util/grub-mkrescue.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 0265f9b81..9b319ac27 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -245,7 +245,7 @@ if test x"${efi_dir}" != x; then fi # build iso image -xorrisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} +xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} From 613b1b2c586be4b77e0e4f536e800c8213e4a8fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 13:44:39 +0200 Subject: [PATCH 158/503] Include /grub.cfg --- util/grub-mkrescue.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 9b319ac27..4f151ac98 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -165,6 +165,7 @@ if test -e "${coreboot_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-coreboot +source $prefix/grub.cfg EOF (for i in ${modules} ; do echo "insmod $i" @@ -221,6 +222,7 @@ if test -e "${efi64_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-efi +source $prefix/grub.cfg EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot From f07ccea799dc9ebc632a44313ad2e94ea55f9efb Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 20:55:12 +0530 Subject: [PATCH 159/503] removed some duplicate code --- conf/any-emu.rmk | 6 +- conf/common.rmk | 23 +++--- disk/lvm.c | 2 +- include/grub/emu/misc.h | 10 +++ include/grub/util/misc.h | 35 +-------- kern/emu/misc.c | 98 +++++++++--------------- {util => kern/emu}/mm.c | 5 -- util/grub-mkrelpath.c | 1 + util/grub-probe.c | 2 +- util/misc.c | 157 --------------------------------------- 10 files changed, 64 insertions(+), 275 deletions(-) rename {util => kern/emu}/mm.c (92%) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index ffaabcd2f..cb0ec873f 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -10,9 +10,9 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ \ - kern/emu/main.c kern/emu/misc.c kern/emu/getroot.c \ - kern/emu/time.c kern/emu/hostdisk.c kern/emu/hostfs.c \ - kern/emu/console.c \ + kern/emu/main.c kern/emu/mm.c kern/emu/misc.c \ + kern/emu/getroot.c kern/emu/time.c kern/emu/hostdisk.c \ + kern/emu/hostfs.c kern/emu/console.c \ \ gnulib/progname.c disk/host.c kernel_img_HEADERS += datetime.h emu/misc.h diff --git a/conf/common.rmk b/conf/common.rmk index 6267d7818..a08e0d3c0 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -6,7 +6,7 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ - util/misc.c + util/misc.c kern/emu/misc.c ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c @@ -16,16 +16,15 @@ endif # For grub-mkelfimage. bin_UTILITIES += grub-mkelfimage -grub_mkelfimage_SOURCES = gnulib/progname.c \ - util/elf/grub-mkimage.c util/misc.c \ - util/resolve.c +grub_mkelfimage_SOURCES = gnulib/progname.c util/elf/grub-mkimage.c \ + util/misc.c kern/emu/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 = gnulib/progname.c util/grub-probe.c \ - kern/emu/hostdisk.c util/misc.c kern/emu/getroot.c util/mm.c \ + kern/emu/hostdisk.c util/misc.c kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ kern/parser.c kern/partition.c kern/file.c kern/list.c \ \ @@ -61,7 +60,7 @@ grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ - util/misc.c util/mm.c \ + util/misc.c kern/emu/misc.c kern/emu/mm.c \ kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ disk/host.c disk/loopback.c kern/list.c kern/command.c \ lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c \ @@ -83,14 +82,14 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ # For grub-mkfont. ifeq ($(enable_grub_mkfont), yes) bin_UTILITIES += grub-mkfont -grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c +grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c kern/emu/misc.c grub_mkfont_CFLAGS = $(freetype_cflags) grub_mkfont_LDFLAGS = $(freetype_libs) endif # For grub-mkrelpath. bin_UTILITIES += grub-mkrelpath -grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c +grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c bin_UTILITIES += grub-bin2h grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c @@ -104,7 +103,7 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h bin_UTILITIES += grub-script-check util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ - util/grub-script-check.c util/misc.c util/mm.c \ + util/grub-script-check.c util/misc.c kern/emu/misc.c kern/emu/mm.c \ script/main.c script/script.c script/function.c script/lexer.c \ kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ @@ -187,7 +186,7 @@ DISTCLEANFILES += grub_fstest_init.c # for grub-editenv bin_UTILITIES += grub-editenv -grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c util/mm.c kern/misc.c kern/err.c +grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/misc.c kern/err.c CLEANFILES += grub-editenv # Needed for genmk.rb to work @@ -195,7 +194,7 @@ ifeq (0,1) bin_UTILITIES += grub-macho2img grub-pe2elf endif -grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c +grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c kern/emu/misc.c CLEANFILES += grub-pe2elf grub_macho2img_SOURCES = util/grub-macho2img.c @@ -855,7 +854,7 @@ boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) bin_UTILITIES += grub-mkpasswd-pbkdf2 -grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c util/mm.c kern/err.c +grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 include $(srcdir)/conf/gcry.mk diff --git a/disk/lvm.c b/disk/lvm.c index c2ae82df2..7dde40920 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -25,7 +25,7 @@ #include #ifdef GRUB_UTIL -#include +#include #endif static struct grub_lvm_vg *vg_list; diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index e62aeba08..4e4df2ad2 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -28,4 +28,14 @@ void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); +#ifndef HAVE_VASPRINTF +int EXPORT_FUNC(vasprintf) (char **buf, const char *fmt, va_list ap); +#endif + +#ifndef HAVE_ASPRINTF +int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); +#endif + +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); + #endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 8b78b92ea..48dfbb868 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -28,26 +28,7 @@ #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; - -void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); -void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); -void EXPORT_FUNC(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); +#include char *grub_util_get_path (const char *dir, const char *file); size_t grub_util_get_fp_size (FILE *fp); @@ -59,20 +40,6 @@ 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_VASPRINTF - -int vasprintf (char **buf, const char *fmt, va_list ap); - -#endif - -#ifndef HAVE_ASPRINTF - -int asprintf (char **buf, const char *fmt, ...); - -#endif - -char *xasprintf (const char *fmt, ...); - #ifdef __MINGW32__ #define fseeko fseeko64 diff --git a/kern/emu/misc.c b/kern/emu/misc.c index d8dfc938d..999cdf257 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -62,70 +62,14 @@ grub_util_error (const char *fmt, ...) exit (1); } -void * -grub_malloc (grub_size_t size) -{ - return malloc (size); -} - -void * -grub_zalloc (grub_size_t size) -{ - void *ret; - - ret = malloc (size); - memset (ret, 0, size); - return ret; -} - -void -grub_free (void *ptr) -{ - free (ptr); -} - -void * -grub_realloc (void *ptr, grub_size_t size) -{ - return realloc (ptr, size); -} - -void * -grub_memalign (grub_size_t align, grub_size_t size) -{ - void *p; - -#if defined(HAVE_POSIX_MEMALIGN) - if (align < sizeof (void *)) - align = sizeof (void *); - - else if (align % sizeof (void *)) - grub_fatal ("bad alignment"); - - if (posix_memalign (&p, align, size) != 0) - p = 0; -#elif defined(HAVE_MEMALIGN) - p = memalign (align, size); -#else - (void) align; - (void) size; - grub_fatal ("grub_memalign is not supported"); -#endif - - if (! p) - grub_fatal ("out of memory"); - - return p; -} - void * xmalloc (grub_size_t size) { void *p; - p = grub_malloc (size); + p = malloc (size); if (! p) - grub_fatal ("out of memory"); + grub_util_error ("out of memory"); return p; } @@ -133,9 +77,9 @@ xmalloc (grub_size_t size) void * xrealloc (void *ptr, grub_size_t size) { - ptr = grub_realloc (ptr, size); + ptr = realloc (ptr, size); if (! ptr) - grub_fatal ("out of memory"); + grub_util_error ("out of memory"); return ptr; } @@ -146,13 +90,43 @@ xstrdup (const char *str) size_t len; char *newstr; - len = grub_strlen (str); + len = strlen (str); newstr = (char *) xmalloc (len + 1); - grub_memcpy (newstr, str, len + 1); + memcpy (newstr, str, len + 1); return newstr; } +#ifndef HAVE_VASPRINTF + +int +vasprintf (char **buf, const char *fmt, va_list ap) +{ + /* Should be large enough. */ + *buf = xmalloc (512); + + return vsprintf (*buf, fmt, ap); +} + +#endif + +#ifndef HAVE_ASPRINTF + +int +asprintf (char **buf, const char *fmt, ...) +{ + int status; + va_list ap; + + va_start (ap, fmt); + status = vasprintf (*buf, fmt, ap); + va_end (ap); + + return status; +} + +#endif + char * xasprintf (const char *fmt, ...) { diff --git a/util/mm.c b/kern/emu/mm.c similarity index 92% rename from util/mm.c rename to kern/emu/mm.c index 0e9e9f3a8..803c1c9aa 100644 --- a/util/mm.c +++ b/kern/emu/mm.c @@ -55,8 +55,6 @@ grub_realloc (void *ptr, grub_size_t size) { void *ret; ret = realloc (ptr, size); - if (!ret) - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); return ret; } @@ -78,8 +76,5 @@ grub_memalign (grub_size_t align, grub_size_t size) grub_util_error ("grub_memalign is not supported"); #endif - if (!p) - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); - return p; } diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index 327f0c866..c26fa7b67 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -17,6 +17,7 @@ * along with GRUB. If not, see . */ +#include #include #include #include diff --git a/util/grub-probe.c b/util/grub-probe.c index 1b2606dc7..add942fb4 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include diff --git a/util/misc.c b/util/misc.c index c413352e7..d26e51bbf 100644 --- a/util/misc.c +++ b/util/misc.c @@ -58,53 +58,6 @@ #include #endif -int verbosity = 0; - -void -grub_util_warn (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, _("%s: warn:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - fflush (stderr); -} - -void -grub_util_info (const char *fmt, ...) -{ - if (verbosity > 0) - { - va_list ap; - - fprintf (stderr, _("%s: info:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - fflush (stderr); - } -} - -void -grub_util_error (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, _("%s: error:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - exit (1); -} - #ifdef GRUB_UTIL int grub_err_printf (const char *fmt, ...) @@ -120,41 +73,6 @@ grub_err_printf (const char *fmt, ...) } #endif -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 *newstr; - - len = strlen (str); - newstr = (char *) xmalloc (len + 1); - memcpy (newstr, str, len + 1); - - return newstr; -} - char * grub_util_get_path (const char *dir, const char *file) { @@ -277,34 +195,6 @@ grub_register_exported_symbols (void) } #endif -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); -} - #ifdef __MINGW32__ void @@ -335,53 +225,6 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), } #endif -#ifndef HAVE_VASPRINTF - -int -vasprintf (char **buf, const char *fmt, va_list ap) -{ - /* Should be large enough. */ - *buf = xmalloc (512); - - return vsprintf (*buf, fmt, ap); -} - -#endif - -#ifndef HAVE_ASPRINTF - -int -asprintf (char **buf, const char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (*buf, fmt, ap); - va_end (ap); - - return status; -} - -#endif - -char * -xasprintf (const char *fmt, ...) -{ - va_list ap; - char *result; - - va_start (ap, fmt); - if (vasprintf (&result, fmt, ap) < 0) - { - if (errno == ENOMEM) - grub_util_error ("out of memory"); - return NULL; - } - - return result; -} - #ifdef __MINGW32__ void sync (void) From b84cac2a36828b701a3f8125b8f9e4f9a2db0dc0 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 20:59:45 +0530 Subject: [PATCH 160/503] undo some hunks that were removed by mistake --- kern/emu/mm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kern/emu/mm.c b/kern/emu/mm.c index 803c1c9aa..0e9e9f3a8 100644 --- a/kern/emu/mm.c +++ b/kern/emu/mm.c @@ -55,6 +55,8 @@ grub_realloc (void *ptr, grub_size_t size) { void *ret; ret = realloc (ptr, size); + if (!ret) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); return ret; } @@ -76,5 +78,8 @@ grub_memalign (grub_size_t align, grub_size_t size) grub_util_error ("grub_memalign is not supported"); #endif + if (!p) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + return p; } From 54f83682d4c7e4fc519a837fdb9750f519f79a7b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 21:43:16 +0200 Subject: [PATCH 161/503] Add missing escape --- util/grub-mkrescue.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4f151ac98..2ef9aa8bd 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -165,7 +165,7 @@ if test -e "${coreboot_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-coreboot -source $prefix/grub.cfg +source \$prefix/grub.cfg EOF (for i in ${modules} ; do echo "insmod $i" @@ -222,7 +222,7 @@ if test -e "${efi64_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-efi -source $prefix/grub.cfg +source \$prefix/grub.cfg EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot From bcfd0cf0facdcd1d713f3ff673662fc75426b479 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 May 2010 23:14:23 +0200 Subject: [PATCH 162/503] Pause before returning to menu editor --- normal/menu_entry.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 20d602597..433208116 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -1370,8 +1370,13 @@ grub_menu_entry_run (grub_menu_entry_t entry) goto refresh; case 24: /* C-x */ - if (! run (screen)) - goto fail; + { + int chars_before = grub_normal_get_char_counter (); + run (screen); + + if (chars_before != grub_normal_get_char_counter ()) + grub_wait_after_message (); + } goto refresh; case 18: /* C-r */ From 04d050152fc2069b1a57208e6510af555c7fe732 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 May 2010 00:05:23 +0200 Subject: [PATCH 163/503] Move geode init to bus/cs5536.c --- bus/cs5536.c | 167 ++++++++++++++++++++++++++++++++++++ include/grub/cs5536.h | 2 + kern/mips/yeeloong/init.c | 174 +------------------------------------- 3 files changed, 170 insertions(+), 173 deletions(-) diff --git a/bus/cs5536.c b/bus/cs5536.c index f481397b7..088f4dfc1 100644 --- a/bus/cs5536.c +++ b/bus/cs5536.c @@ -20,6 +20,7 @@ #include #include #include +#include int grub_cs5536_find (grub_pci_device_t *devp) @@ -211,3 +212,169 @@ grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, } return GRUB_ERR_NONE; } + +/* Dump of GPIO connections. FIXME: Remove useless and macroify. */ +static grub_uint32_t gpiodump[] = { + 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000, + 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000, + 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000, + 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000, + 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000, + 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000, + 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x50000000, 0x00000000, 0x00000000, +}; + +static inline void +set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start, + grub_uint16_t len) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_REGIONS_START + num, + ((((grub_uint64_t) start + len - 4) + << GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT) + & GRUB_CS5536_MSR_GL_REGION_TOP_MASK) + | (((grub_uint64_t) start + << GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT) + & GRUB_CS5536_MSR_GL_REGION_BASE_MASK) + | GRUB_CS5536_MSR_GL_REGION_IO + | GRUB_CS5536_MSR_GL_REGION_ENABLE); +} + +static inline void +set_iod (grub_pci_device_t dev, int num, int dest, int start, int mask) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_IOD_START + num, + ((grub_uint64_t) dest << GRUB_CS5536_IOD_DEST_SHIFT) + | (((grub_uint64_t) start & GRUB_CS5536_IOD_ADDR_MASK) + << GRUB_CS5536_IOD_BASE_SHIFT) + | ((mask & GRUB_CS5536_IOD_ADDR_MASK) + << GRUB_CS5536_IOD_MASK_SHIFT)); +} + +static inline void +set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start) +{ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_P2D_START + num, + (((grub_uint64_t) dest) << GRUB_CS5536_P2D_DEST_SHIFT) + | ((grub_uint64_t) (start >> GRUB_CS5536_P2D_LOG_ALIGN) + << GRUB_CS5536_P2D_BASE_SHIFT) + | (((1 << (32 - GRUB_CS5536_P2D_LOG_ALIGN)) - 1) + << GRUB_CS5536_P2D_MASK_SHIFT)); +} + +void +grub_cs5536_init_geode (grub_pci_device_t dev) +{ + int i; + + /* Make sure GPIO is where we expect it to be. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_GPIO); + + /* Setup GPIO. */ + for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++) + ((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE + + GRUB_CS5536_LBAR_GPIO)) [i] = gpiodump[i]; + + /* Enable more BARs. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_MFGPT_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_MFGPT); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_ACPI_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR, + GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); + + /* Setup DIVIL. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, + GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 + | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK, + (~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK, + GRUB_CS5536_DIVIL_LPC_INTERRUPTS); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL, + GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE); + + /* Initialise USB controller. */ + /* FIXME: assign adresses dynamically. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | 0x05024000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE + | (0x20ULL << GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT) + | 0x05023000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_CONTROLLER_BASE, + GRUB_CS5536_MSR_USB_BASE_BUS_MASTER + | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05020000); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE, + GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05022000); + set_p2d (dev, 0, GRUB_CS5536_DESTINATION_USB, 0x05020000); + set_p2d (dev, 1, GRUB_CS5536_DESTINATION_USB, 0x05022000); + set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000); + set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000); + + { + volatile grub_uint32_t *oc; + oc = grub_pci_device_map_range (dev, 0x05022000, + GRUB_CS5536_USB_OPTION_REGS_SIZE); + + oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] = + (oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] + & ~GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK) + | GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC; + grub_pci_device_unmap_range (dev, oc, GRUB_CS5536_USB_OPTION_REGS_SIZE); + } + + /* Setup IDE controller. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR, + GRUB_CS5536_LBAR_IDE + | GRUB_CS5536_MSR_IDE_IO_BAR_UNITS); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CFG, + GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_TIMING, + (GRUB_CS5536_MSR_IDE_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT) + | (GRUB_CS5536_MSR_IDE_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT)); + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CAS_TIMING, + (GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT) + | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT) + | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 + << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT)); + + /* Setup Geodelink PCI. */ + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_PCI_CTRL, + (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT) + | (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT) + | (8ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT) + | GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE + | GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE); + + /* Setup windows. */ + set_io_space (dev, 0, GRUB_CS5536_LBAR_SMBUS, GRUB_CS5536_SMBUS_REGS_SIZE); + set_io_space (dev, 1, GRUB_CS5536_LBAR_GPIO, GRUB_CS5536_GPIO_REGS_SIZE); + set_io_space (dev, 2, GRUB_CS5536_LBAR_MFGPT, GRUB_CS5536_MFGPT_REGS_SIZE); + set_io_space (dev, 3, GRUB_CS5536_LBAR_IRQ_MAP, GRUB_CS5536_IRQ_MAP_REGS_SIZE); + set_io_space (dev, 4, GRUB_CS5536_LBAR_PM, GRUB_CS5536_PM_REGS_SIZE); + set_io_space (dev, 5, GRUB_CS5536_LBAR_ACPI, GRUB_CS5536_ACPI_REGS_SIZE); + set_iod (dev, 0, GRUB_CS5536_DESTINATION_IDE, GRUB_ATA_CH0_PORT1, 0xffff8); + set_iod (dev, 1, GRUB_CS5536_DESTINATION_ACC, GRUB_CS5536_LBAR_ACC, 0xfff80); + set_iod (dev, 2, GRUB_CS5536_DESTINATION_IDE, GRUB_CS5536_LBAR_IDE, 0xffff0); +} diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index a16fb7a09..cd17e11fc 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -183,6 +183,8 @@ grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase); grub_err_t EXPORT_FUNC (grub_cs5536_init_smbus) (grub_pci_device_t dev, grub_uint16_t divisor, grub_port_t *smbbase); + +void grub_cs5536_init_geode (grub_pci_device_t dev); #endif #endif diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 5c3340f39..fa02df601 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -31,7 +31,6 @@ #include #include #include -#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); @@ -68,63 +67,6 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, return GRUB_ERR_NONE; } -/* Dump of GPIO connections. FIXME: Remove useless and macroify. */ -static grub_uint32_t gpiodump[] = { - 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000, - 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000, - 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000, - 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000, - 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, - 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000, - 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000, - 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000, - 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x50000000, 0x00000000, 0x00000000, -}; - -static inline void -set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start, - grub_uint16_t len) -{ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_REGIONS_START + num, - ((((grub_uint64_t) start + len - 4) - << GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT) - & GRUB_CS5536_MSR_GL_REGION_TOP_MASK) - | (((grub_uint64_t) start - << GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT) - & GRUB_CS5536_MSR_GL_REGION_BASE_MASK) - | GRUB_CS5536_MSR_GL_REGION_IO - | GRUB_CS5536_MSR_GL_REGION_ENABLE); -} - -static inline void -set_iod (grub_pci_device_t dev, int num, int dest, int start, int mask) -{ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_IOD_START + num, - ((grub_uint64_t) dest << GRUB_CS5536_IOD_DEST_SHIFT) - | (((grub_uint64_t) start & GRUB_CS5536_IOD_ADDR_MASK) - << GRUB_CS5536_IOD_BASE_SHIFT) - | ((mask & GRUB_CS5536_IOD_ADDR_MASK) - << GRUB_CS5536_IOD_MASK_SHIFT)); -} - -static inline void -set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start) -{ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_P2D_START + num, - (((grub_uint64_t) dest) << GRUB_CS5536_P2D_DEST_SHIFT) - | ((grub_uint64_t) (start >> GRUB_CS5536_P2D_LOG_ALIGN) - << GRUB_CS5536_P2D_BASE_SHIFT) - | (((1 << (32 - GRUB_CS5536_P2D_LOG_ALIGN)) - 1) - << GRUB_CS5536_P2D_MASK_SHIFT)); -} - void grub_machine_init (void) { @@ -180,121 +122,7 @@ grub_machine_init (void) grub_arch_highmemsize = 0; } - /* Make sure GPIO is where we expect it to be. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR, - GRUB_CS5536_LBAR_TURN_ON - | GRUB_CS5536_LBAR_GPIO); - - /* Setup GPIO. */ - for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++) - ((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE - + GRUB_CS5536_LBAR_GPIO)) [i] - = gpiodump[i]; - - /* Enable more BARs. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR, - GRUB_CS5536_LBAR_TURN_ON - | GRUB_CS5536_LBAR_IRQ_MAP); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_MFGPT_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_MFGPT); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_ACPI_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); - - /* Setup DIVIL. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, - GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK, - (~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK, - GRUB_CS5536_DIVIL_LPC_INTERRUPTS); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL, - GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE); - - /* Initialise USB controller. */ - /* FIXME: assign adresses dynamically. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, - GRUB_CS5536_MSR_USB_BASE_BUS_MASTER - | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE - | 0x05024000); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, - GRUB_CS5536_MSR_USB_BASE_BUS_MASTER - | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE - | (0x20ULL - << GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT) - | 0x05023000); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_CONTROLLER_BASE, - GRUB_CS5536_MSR_USB_BASE_BUS_MASTER - | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE - | 0x05020000); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE, - GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE - | 0x05022000); - set_p2d (dev, 0, GRUB_CS5536_DESTINATION_USB, 0x05020000); - set_p2d (dev, 1, GRUB_CS5536_DESTINATION_USB, 0x05022000); - set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000); - set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000); - - { - volatile grub_uint32_t *oc; - oc = grub_pci_device_map_range (dev, 0x05022000, - GRUB_CS5536_USB_OPTION_REGS_SIZE); - - oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] = - (oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] - & ~GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK) - | GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC; - grub_pci_device_unmap_range (dev, oc, GRUB_CS5536_USB_OPTION_REGS_SIZE); - } - - - /* Setup IDE controller. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR, - GRUB_CS5536_LBAR_IDE - | GRUB_CS5536_MSR_IDE_IO_BAR_UNITS); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CFG, - GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_TIMING, - (GRUB_CS5536_MSR_IDE_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT) - | (GRUB_CS5536_MSR_IDE_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT)); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CAS_TIMING, - (GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 - << GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT) - | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT) - | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT)); - - /* Setup Geodelink PCI. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_PCI_CTRL, - (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT) - | (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT) - | (8ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT) - | GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE - | GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE); - - /* Setup windows. */ - set_io_space (dev, 0, GRUB_CS5536_LBAR_SMBUS, - GRUB_CS5536_SMBUS_REGS_SIZE); - set_io_space (dev, 1, GRUB_CS5536_LBAR_GPIO, GRUB_CS5536_GPIO_REGS_SIZE); - set_io_space (dev, 2, GRUB_CS5536_LBAR_MFGPT, - GRUB_CS5536_MFGPT_REGS_SIZE); - set_io_space (dev, 3, GRUB_CS5536_LBAR_IRQ_MAP, - GRUB_CS5536_IRQ_MAP_REGS_SIZE); - set_io_space (dev, 4, GRUB_CS5536_LBAR_PM, GRUB_CS5536_PM_REGS_SIZE); - set_io_space (dev, 5, GRUB_CS5536_LBAR_ACPI, GRUB_CS5536_ACPI_REGS_SIZE); - set_iod (dev, 0, GRUB_CS5536_DESTINATION_IDE, GRUB_ATA_CH0_PORT1, - 0xffff8); - set_iod (dev, 1, GRUB_CS5536_DESTINATION_ACC, GRUB_CS5536_LBAR_ACC, - 0xfff80); - set_iod (dev, 2, GRUB_CS5536_DESTINATION_IDE, GRUB_CS5536_LBAR_IDE, - 0xffff0); + grub_cs5536_init_geode (dev); /* Setup PCI controller. */ *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER From 0a58eb2e3ac748bf613cb0270b22fe36f6c75bb6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 May 2010 10:56:52 +0200 Subject: [PATCH 164/503] move fwstart.S to boot/ --- {kern => boot}/mips/yeeloong/fwstart.S | 0 conf/mips-yeeloong.rmk | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {kern => boot}/mips/yeeloong/fwstart.S (100%) diff --git a/kern/mips/yeeloong/fwstart.S b/boot/mips/yeeloong/fwstart.S similarity index 100% rename from kern/mips/yeeloong/fwstart.S rename to boot/mips/yeeloong/fwstart.S diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 233d8dae6..fbc23db7b 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -36,7 +36,7 @@ kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ kernel_img_FORMAT = binary pkglib_IMAGES += fwstart.img -fwstart_img_SOURCES = kern/$(target_cpu)/$(target_machine)/fwstart.S +fwstart_img_SOURCES = boot/$(target_cpu)/$(target_machine)/fwstart.S fwstart_img_CFLAGS = $(COMMON_CFLAGS) fwstart_img_ASFLAGS = $(COMMON_ASFLAGS) fwstart_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ From 469ed9410b4a1e7c20948a4ced73e8f3343379be Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 09:58:02 +0200 Subject: [PATCH 165/503] Fix i386-pc compilation --- conf/i386.rmk | 6 ++++++ include/grub/i386/pci.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/conf/i386.rmk b/conf/i386.rmk index 3d7f42804..bf2b80821 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -56,6 +56,12 @@ pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cs5536.mod +pkglib_MODULES += cs5536.mod +cs5536_mod_SOURCES = bus/cs5536.c +cs5536_mod_CFLAGS = $(COMMON_CFLAGS) +cs5536_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For lspci.mod pkglib_MODULES += lspci.mod lspci_mod_SOURCES = commands/lspci.c diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index bab42adb6..795dec58b 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -80,7 +80,7 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), static inline void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - void *mem __attribute__ ((unused)), + volatile void *mem __attribute__ ((unused)), grub_size_t size __attribute__ ((unused))) { } From a8a145eb2fa1656dfbd92da3ea36af05544c206f Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 5 May 2010 14:05:06 +0530 Subject: [PATCH 166/503] simplify cmdblock with cmdlist --- include/grub/script_sh.h | 19 ++++------------- script/execute.c | 6 +++--- script/parser.y | 10 +++------ script/script.c | 46 +++++++++++++++++----------------------- util/grub-script-check.c | 2 +- 5 files changed, 31 insertions(+), 52 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index b55b6a806..53f4f13bb 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -82,15 +82,6 @@ struct grub_script_cmdline struct grub_script_arglist *arglist; }; -/* 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 { @@ -234,8 +225,6 @@ grub_script_add_arglist (struct grub_parser_param *state, struct grub_script_cmd * grub_script_create_cmdline (struct grub_parser_param *state, 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, @@ -262,9 +251,9 @@ grub_script_create_cmdmenu (struct grub_parser_param *state, 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); +grub_script_append_cmd (struct grub_parser_param *state, + struct grub_script_cmd *list, + struct grub_script_cmd *last); struct grub_script_arg * grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg *arg, @@ -301,7 +290,7 @@ 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_cmdlist (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd); diff --git a/script/execute.c b/script/execute.c index 40f161267..e10558b4d 100644 --- a/script/execute.c +++ b/script/execute.c @@ -269,13 +269,13 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Execute a block of one or more commands. */ grub_err_t -grub_script_execute_cmdblock (struct grub_script_cmd *cmd) +grub_script_execute_cmdlist (struct grub_script_cmd *list) { int ret = 0; - struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd; + struct grub_script_cmd *cmd; /* Loop over every command and execute it. */ - for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next) + for (cmd = list->next; cmd; cmd = cmd->next) ret = grub_script_execute_cmd (cmd); return ret; diff --git a/script/parser.y b/script/parser.y index b5815ea8d..cc08af37a 100644 --- a/script/parser.y +++ b/script/parser.y @@ -96,9 +96,7 @@ script: newlines0 } | script statement delimiter newlines0 { - struct grub_script_cmdblock *cmdblock; - cmdblock = (struct grub_script_cmdblock *) $1; - $$ = grub_script_add_cmd (state, cmdblock, $2); + $$ = grub_script_append_cmd (state, $1, $2); } | error { @@ -183,13 +181,11 @@ command: grubcmd { $$ = $1; } /* A list of commands. */ commands1: newlines0 command { - $$ = grub_script_add_cmd (state, 0, $2); + $$ = grub_script_append_cmd (state, 0, $2); } | commands1 delimiters1 command { - struct grub_script_cmdblock *cmdblock; - cmdblock = (struct grub_script_cmdblock *) $1; - $$ = grub_script_add_cmd (state, cmdblock, $3); + $$ = grub_script_append_cmd (state, $1, $3); } ; diff --git a/script/script.c b/script/script.c index 4c87d9491..9cee40dcb 100644 --- a/script/script.c +++ b/script/script.c @@ -291,46 +291,40 @@ grub_script_create_cmdmenu (struct grub_parser_param *state, 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. */ +/* Create a chain of commands. LAST contains the command that should + be added at the end of LIST's list. If LIST is zero, a new list + 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_script_append_cmd (struct grub_parser_param *state, + struct grub_script_cmd *list, + struct grub_script_cmd *last) { struct grub_script_cmd *ptr; - grub_dprintf ("scripting", "cmdblock\n"); + grub_dprintf ("scripting", "append command\n"); - if (!cmd) - return (struct grub_script_cmd *) cmdblock; + if (! last) + return list; - if (!cmdblock) + if (! list) { - cmdblock = grub_script_malloc (state, sizeof (*cmdblock)); - if (!cmdblock) + list = grub_script_malloc (state, sizeof (*list)); + if (! list) return 0; - cmdblock->cmd.exec = grub_script_execute_cmdblock; - cmdblock->cmd.next = 0; - cmdblock->cmdlist = cmd; - cmd->next = 0; + list->exec = grub_script_execute_cmdlist; + list->next = last; } else { - if (!cmdblock->cmdlist) - cmdblock->cmdlist = cmd; - else - { - ptr = cmdblock->cmdlist; - while (ptr->next) - ptr = ptr->next; - ptr->next = cmd; - } + ptr = list; + while (ptr->next) + ptr = ptr->next; + + ptr->next = last; } - return (struct grub_script_cmd *) cmdblock; + return list; } diff --git a/util/grub-script-check.c b/util/grub-script-check.c index dc732aa01..3b7ab295d 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -70,7 +70,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd __attribute__ ((unused) } grub_err_t -grub_script_execute_cmdblock (struct grub_script_cmd *cmd __attribute__ ((unused))) +grub_script_execute_cmdlist (struct grub_script_cmd *cmd __attribute__ ((unused))) { return 0; } From 839ced08f5cbc496087e21a51784d568eda96f7b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 10:40:48 +0200 Subject: [PATCH 167/503] separate function to allocate DMA memory --- bus/pci.c | 43 +++++++++++++++++++ bus/usb/ohci.c | 62 ++++++++++++++++------------ bus/usb/uhci.c | 6 +-- bus/usb/usbtrans.c | 91 +++++++++++++++++++++++++++++++++-------- include/grub/pci.h | 9 ++++ include/grub/usbtrans.h | 2 +- kern/misc.c | 3 +- 7 files changed, 167 insertions(+), 49 deletions(-) diff --git a/bus/pci.c b/bus/pci.c index a08e53446..2fe9d764e 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -19,6 +19,49 @@ #include #include +#include + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 +struct grub_pci_dma_chunk * +grub_memalign_dma32 (grub_size_t align, grub_size_t size) +{ + return grub_memalign (align, size); +} + +void +grub_dma_free (struct grub_pci_dma_chunk *ch) +{ + grub_free (ch); +} +#endif + +#ifdef GRUB_MACHINE_MIPS_YEELOONG +void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000); +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return ((grub_uint32_t) ch) & 0x1fffffff; +} +#else + +void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ch; +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (grub_uint32_t) ch; +} + +#endif grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index de20a1491..81ce3294d 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -72,6 +72,7 @@ struct grub_ohci volatile grub_uint32_t *iobase; volatile struct grub_ohci_hcca *hcca; grub_uint32_t hcca_addr; + struct grub_pci_dma_chunk *hcca_chunk; struct grub_ohci *next; }; @@ -136,7 +137,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_uint32_t revision; grub_uint32_t frame_interval; int cs5536; - grub_uint32_t hcca_addr; /* Determine IO base address. */ grub_dprintf ("ohci", "pciid = %x\n", pciid); @@ -157,7 +157,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev, basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg); - } else { @@ -198,14 +197,12 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_dprintf ("ohci", "base=%p\n", o->iobase); - /* FIXME: create proper abstraction for this. */ -#ifdef GRUB_MACHINE_MIPS_YEELOONG - hcca_addr = 0x05000100; -#else /* Reserve memory for the HCCA. */ - hcca_addr = (grub_uint32_t) grub_memalign (256, 256); -#endif - o->hcca = grub_pci_device_map_range (dev, hcca_addr, 256); + o->hcca_chunk = grub_memalign_dma32 (256, 256); + if (! o->hcca_chunk) + return 1; + o->hcca = grub_dma_get_virt (o->hcca_chunk); + o->hcca_addr = grub_dma_get_phys (o->hcca_chunk); /* Check if the OHCI revision is actually 1.0 as supported. */ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); @@ -236,7 +233,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, hcca_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -289,7 +286,7 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) 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_size_t size, grub_uint32_t data) { grub_uint32_t token; grub_uint32_t buffer; @@ -321,7 +318,7 @@ grub_ohci_transaction (grub_ohci_td_t td, token |= toggle << 24; token |= 1 << 25; - buffer = (grub_uint32_t) data; + buffer = data; buffer_end = buffer + size - 1; td->token = grub_cpu_to_le32 (token); @@ -336,7 +333,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, { struct grub_ohci *o = (struct grub_ohci *) dev->data; grub_ohci_ed_t ed; + grub_uint32_t ed_addr; + struct grub_pci_dma_chunk *ed_chunk, *td_list_chunk; grub_ohci_td_t td_list; + grub_uint32_t td_list_addr; grub_uint32_t target; grub_uint32_t td_tail; grub_uint32_t td_head; @@ -346,18 +346,23 @@ grub_ohci_transfer (grub_usb_controller_t dev, int i; /* Allocate an Endpoint Descriptor. */ - ed = grub_memalign (16, sizeof (*ed)); - if (! ed) + ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); + if (! ed_chunk) return GRUB_USB_ERR_INTERNAL; + ed = grub_dma_get_virt (ed_chunk); + ed_addr = grub_dma_get_phys (ed_chunk); - td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1)); - if (! td_list) + td_list_chunk = grub_memalign_dma32 (256, sizeof (*td_list) + * (transfer->transcnt + 1)); + if (! td_list_chunk) { - grub_free ((void *) ed); + grub_dma_free (ed_chunk); return GRUB_USB_ERR_INTERNAL; } + td_list = grub_dma_get_virt (td_list_chunk); + td_list_addr = grub_dma_get_phys (td_list_chunk); - grub_dprintf ("ohci", "alloc=%p\n", td_list); + grub_dprintf ("ohci", "alloc=%p/0x%x\n", td_list, td_list_addr); /* Setup all Transfer Descriptors. */ for (i = 0; i < transfer->transcnt; i++) @@ -367,7 +372,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, 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]); + td_list[i].next_td = grub_cpu_to_le32 (td_list_addr + + (i + 1) * sizeof (td_list[0])); } /* Setup the Endpoint Descriptor. */ @@ -384,9 +390,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Set the maximum packet size. */ target |= transfer->max << 16; - td_head = (grub_uint32_t) td_list; + td_head = td_list_addr; - td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; + td_tail = td_list_addr + transfer->transcnt * sizeof (*td_list); ed->target = grub_cpu_to_le32 (target); ed->td_head = grub_cpu_to_le32 (td_head); @@ -413,7 +419,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 2); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); /* Enable the Bulk list. */ control |= 1 << 5; @@ -440,10 +446,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, 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, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - (grub_uint32_t) ed); + ed_addr); /* Enable the Control list. */ control |= 1 << 4; @@ -484,9 +489,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, { grub_uint8_t errcode; grub_ohci_td_t tderr; + grub_uint32_t td_err_addr; - tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o, - GRUB_OHCI_REG_DONEHEAD); + td_err_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD); + + tderr = (grub_ohci_td_t) ((char *) td_list + + (td_err_addr - td_list_addr)); errcode = tderr->token >> 28; switch (errcode) diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 947f2367b..6e47c38ef 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -380,7 +380,7 @@ 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_uint32_t data) { grub_uhci_td_t td; static const unsigned int tf[] = { 0x69, 0xE1, 0x2D }; @@ -398,7 +398,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, } grub_dprintf ("uhci", - "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n", + "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=0x%x td=%p\n", endp, type, addr, toggle, size, data, td); /* Don't point to any TD, just terminate. */ @@ -418,7 +418,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, td->token = ((size << 21) | (toggle << 19) | (endp << 15) | (addr << 8) | tf[type]); - td->buffer = (grub_uint32_t) data; + td->buffer = data; return td; } diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 09e7af83e..f59d5ec77 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -29,30 +30,59 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t request, grub_uint16_t value, grub_uint16_t index, - grub_size_t size, char *data) + grub_size_t size0, char *data_in) { int i; grub_usb_transfer_t transfer; int datablocks; - struct grub_usb_packet_setup setupdata; + struct grub_usb_packet_setup *setupdata; + grub_uint32_t setupdata_addr; grub_usb_err_t err; unsigned int max; + struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk; + char *data; + grub_uint32_t data_addr; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size ? : 16); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + grub_memcpy (data, data_in, size); 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)); + transfer = grub_malloc (sizeof (*transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata)); + if (! setupdata_chunk) + { + grub_free (transfer); + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata = grub_dma_get_virt (setupdata_chunk); + setupdata_addr = grub_dma_get_phys (setupdata_chunk); /* Determine the maximum packet size. */ - if (dev->initialized) + if (dev->initialized && dev->descdev.maxsize0) max = dev->descdev.maxsize0; else max = 64; + grub_dprintf ("usb", "transfer = %p, dev = %p\n", transfer, dev); + datablocks = (size + max - 1) / max; /* XXX: Discriminate between different types of control @@ -71,18 +101,20 @@ grub_usb_control_msg (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (setupdata_chunk); + grub_dma_free (data_chunk); return grub_errno; } /* Build a Setup packet. XXX: Endianness. */ - setupdata.reqtype = reqtype; - setupdata.request = request; - setupdata.value = value; - setupdata.index = index; - setupdata.length = size; - transfer->transactions[0].size = sizeof (setupdata); + 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].data = setupdata_addr; transfer->transactions[0].toggle = 0; /* Now the data... XXX: Is this the right way to transfer control @@ -99,13 +131,13 @@ grub_usb_control_msg (grub_usb_device_t dev, tr->pid = GRUB_USB_TRANSFER_TYPE_IN; else tr->pid = GRUB_USB_TRANSFER_TYPE_OUT; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= max; } /* End with an empty OUT transaction. */ transfer->transactions[datablocks + 1].size = 0; - transfer->transactions[datablocks + 1].data = NULL; + transfer->transactions[datablocks + 1].data = 0; if (reqtype & 128) transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; else @@ -117,13 +149,17 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + grub_dma_free (setupdata_chunk); + + grub_memcpy (data_in, data, size0); return err; } static grub_usb_err_t grub_usb_bulk_readwrite (grub_usb_device_t dev, - int endpoint, grub_size_t size, char *data, + int endpoint, grub_size_t size0, char *data_in, grub_transfer_type_t type) { int i; @@ -132,6 +168,19 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, unsigned int max; grub_usb_err_t err; int toggle = dev->toggle[endpoint]; + char *data; + grub_uint32_t data_addr; + struct grub_pci_dma_chunk *data_chunk; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + if (type == GRUB_USB_TRANSFER_TYPE_OUT) + grub_memcpy (data, data_in, size); /* Use the maximum packet size given in the endpoint descriptor. */ if (dev->initialized) @@ -150,7 +199,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, /* Create a transfer. */ transfer = grub_malloc (sizeof (struct grub_usb_transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; @@ -167,6 +219,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (data_chunk); return grub_errno; } @@ -181,7 +234,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, tr->toggle = toggle; toggle = toggle ? 0 : 1; tr->pid = type; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= tr->size; } @@ -191,6 +244,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + + if (type == GRUB_USB_TRANSFER_TYPE_IN) + grub_memcpy (data_in, data, size0); return err; } diff --git a/include/grub/pci.h b/include/grub/pci.h index 8a653c43e..fff4d3e3a 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -109,6 +109,15 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, int reg); void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); + +struct grub_pci_dma_chunk; + +struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, + grub_size_t size); +void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); +void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); +grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); + #endif #endif /* GRUB_PCI_H */ diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 7e4a9d7ee..8c739684e 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -37,7 +37,7 @@ struct grub_usb_transaction int size; int toggle; grub_transfer_type_t pid; - char *data; + grub_uint32_t data; }; typedef struct grub_usb_transaction *grub_usb_transaction_t; diff --git a/kern/misc.c b/kern/misc.c index 9d8fc70da..e86043c15 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -189,7 +189,7 @@ grub_real_dprintf (const char *file, const int line, const char *condition, const char *debug = grub_env_get ("debug"); if (! debug) - return; + debug = "usb,ohci"; if (grub_strword (debug, "all") || grub_strword (debug, condition)) { @@ -197,6 +197,7 @@ grub_real_dprintf (const char *file, const int line, const char *condition, va_start (args, fmt); grub_vprintf (fmt, args); va_end (args); + grub_refresh (); } } From dcf937195ca499ce0b672e98e81c92891ea3abd2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 10:49:03 +0200 Subject: [PATCH 168/503] revert accidental debugging commit --- kern/misc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kern/misc.c b/kern/misc.c index e86043c15..9d8fc70da 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -189,7 +189,7 @@ grub_real_dprintf (const char *file, const int line, const char *condition, const char *debug = grub_env_get ("debug"); if (! debug) - debug = "usb,ohci"; + return; if (grub_strword (debug, "all") || grub_strword (debug, condition)) { @@ -197,7 +197,6 @@ grub_real_dprintf (const char *file, const int line, const char *condition, va_start (args, fmt); grub_vprintf (fmt, args); va_end (args); - grub_refresh (); } } From 342bf06e583bb768060d52783272e0e91abc10e3 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 5 May 2010 14:47:50 +0530 Subject: [PATCH 169/503] function parameters support --- conf/tests.rmk | 4 ++ include/grub/script_sh.h | 13 +++++- script/execute.c | 75 +++++++++++++++++++++++++++++++--- script/function.c | 9 ---- script/yylex.l | 7 ++-- tests/grub_script_functions.in | 63 ++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 20 deletions(-) create mode 100644 tests/grub_script_functions.in diff --git a/conf/tests.rmk b/conf/tests.rmk index 9af2f8f86..9144e5528 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -71,6 +71,9 @@ grub_script_dollar_SOURCES = tests/grub_script_dollar.in check_SCRIPTS += grub_script_comments grub_script_comments_SOURCES = tests/grub_script_comments.in +check_SCRIPTS += grub_script_functions +grub_script_functions_SOURCES = tests/grub_script_functions.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -87,6 +90,7 @@ SCRIPTED_TESTS += grub_script_blanklines SCRIPTED_TESTS += grub_script_final_semicolon SCRIPTED_TESTS += grub_script_dollar SCRIPTED_TESTS += grub_script_comments +SCRIPTED_TESTS += grub_script_functions # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 53f4f13bb..730aa3005 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -73,6 +73,15 @@ struct grub_script_arglist int argcount; }; +/* Scope for grub script constructs. */ +struct grub_script_scope +{ + struct grub_script_scope *next; + + char **args; + unsigned int argc; +}; + /* A single command line. */ struct grub_script_cmdline { @@ -329,8 +338,8 @@ grub_script_function_t grub_script_function_create (struct grub_script_arg *func 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); +grub_err_t grub_script_function_call (grub_script_function_t func, + int argc, char **args); char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count); diff --git a/script/execute.c b/script/execute.c index e10558b4d..571b6785b 100644 --- a/script/execute.c +++ b/script/execute.c @@ -30,6 +30,52 @@ is sizeof (int) * 3, and one extra for a possible -ve sign. */ #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) +static struct grub_script_scope *scope = 0; + +static char * +grub_script_env_get (const char *name) +{ + char *p = 0; + unsigned long num = 0; + + if (! scope) + return grub_env_get (name); + + if (grub_isdigit (name[0])) + { + num = grub_strtoul (name, &p, 10); + if (p && *p == '\0') + { + if (num == 0) + return 0; /* XXX no file name, for now. */ + + return (num > scope->argc ? 0 : scope->args[num - 1]); + } + else + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "bad variabe name substitution"); + return 0; + } + } + else if (grub_strcmp (name, "#") == 0) + { + static char buf[32]; /* Rewritten everytime. */ + grub_snprintf (buf, sizeof (buf), "%u", scope->argc); + return buf; + } + else + return grub_env_get (name); +} + +static grub_err_t +grub_script_env_set (const char *name, const char *val) +{ + if (grub_isdigit (name[0]) || grub_strcmp (name, "#") == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad variable name"); + + return grub_env_set (name, val); +} + static grub_err_t grub_script_execute_cmd (struct grub_script_cmd *cmd) { @@ -143,7 +189,7 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c switch (arg->type) { case GRUB_SCRIPT_ARG_TYPE_VAR: - value = grub_env_get (arg->str); + value = grub_script_env_get (arg->str); while (value && *value && (ptr = move_to_next(&value))) { empty = 0; @@ -168,7 +214,7 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c case GRUB_SCRIPT_ARG_TYPE_DQVAR: empty = 0; - append (grub_env_get (arg->str), 0); + append (grub_script_env_get (arg->str), 0); break; } arg = arg->next; @@ -191,6 +237,23 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c return argv; } +/* Execute a function call. */ +grub_err_t +grub_script_function_call (grub_script_function_t func, int argc, char **args) +{ + grub_err_t ret = 0; + struct grub_script_scope new_scope; + + new_scope.argc = argc; + new_scope.args = args; + grub_list_push (GRUB_AS_LIST_P (&scope), GRUB_AS_LIST (&new_scope)); + + ret = grub_script_execute (func->func); + + grub_list_pop (GRUB_AS_LIST_P (&scope)); + return ret; +} + /* Execute a single command line. */ grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd) @@ -232,12 +295,12 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Create two strings and set the variable. */ *eq = '\0'; eq++; - grub_env_set (assign, eq); + grub_script_env_set (assign, eq); } grub_free (assign); grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); - grub_env_set ("?", errnobuf); + grub_script_env_set ("?", errnobuf); grub_print_error (); @@ -291,7 +354,7 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd) /* 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 ("?"); + result = grub_script_env_get ("?"); grub_errno = GRUB_ERR_NONE; @@ -320,7 +383,7 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) result = 0; for (i = 0; i < argcount; i++) { - grub_env_set (cmdfor->name->str, args[i]); + grub_script_env_set (cmdfor->name->str, args[i]); result = grub_script_execute_cmd (cmdfor->list); grub_free (args[i]); } diff --git a/script/function.c b/script/function.c index ded470c4e..82c753bcd 100644 --- a/script/function.c +++ b/script/function.c @@ -115,12 +115,3 @@ grub_script_function_iterate (int (*iterate) (grub_script_function_t)) 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/script/yylex.l b/script/yylex.l index 7d4ea9e4e..f563ac30d 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -119,7 +119,8 @@ DIGITS [[:digit:]]+ NAME [[:alpha:]_][[:alnum:][:digit:]_]* ESC \\. -VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\} +SPECIAL \?|\# +VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|${SPECIAL}|$\{{SPECIAL}\} DQSTR \"([^\\\"]|{ESC})*\" SQSTR \'[^\']*\' WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ @@ -221,7 +222,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ } { - \? | + {SPECIAL} | {DIGITS} | {NAME} { COPY (yytext, yyleng); @@ -231,7 +232,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ else ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); } - \{\?\} | + \{{SPECIAL}\} | \{{DIGITS}\} | \{{NAME}\} { yytext[yyleng - 1] = '\0'; diff --git a/tests/grub_script_functions.in b/tests/grub_script_functions.in new file mode 100644 index 000000000..41af87474 --- /dev/null +++ b/tests/grub_script_functions.in @@ -0,0 +1,63 @@ +#! @builddir@/grub-shell-tester + +# Run GRUB script in a Qemu instance +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +echo parameter count +function fcount { + echo "$#" +} + +fcount +fcount a +fcount a b + +echo parameter count, with nesting +function ffcount { + echo "$#" + fcount + fcount a + fcount a b +} + +ffcount +ffcount 1 +ffcount 1 2 + +echo parameters +function fparam { + echo 1 $1 + echo 2 $2 + echo 3 $3 +} + +fparam +fparam a +fparam a b + +echo parameters, with nesting +function ffparam { + echo 1 $1 + echo 2 $2 + echo 3 $3 + fparam + fparam a + fparam a b +} + +ffparam +ffparam 1 +ffparam 1 2 From a7aa28248b1f005b09392b4f25027a896ef0eca6 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 5 May 2010 15:34:26 +0530 Subject: [PATCH 170/503] break command support --- conf/common.rmk | 12 +++--- conf/tests.rmk | 4 ++ include/grub/script_sh.h | 4 ++ script/execute.c | 47 +++++++++++++++++++-- script/main.c | 3 ++ tests/grub_script_break.in | 86 ++++++++++++++++++++++++++++++++++++++ util/grub-script-check.c | 8 ++++ 7 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 tests/grub_script_break.in diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..ed96ce320 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -103,12 +103,12 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h # For grub-script-check. bin_UTILITIES += grub-script-check util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h -grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ - util/grub-script-check.c util/misc.c util/mm.c \ - script/main.c script/script.c script/function.c script/lexer.c \ - kern/handler.c kern/err.c kern/parser.c kern/list.c \ - kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ - grub_script.yy.c +grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c \ + gnulib/getline.c util/grub-script-check.c util/misc.c \ + util/mm.c script/main.c script/script.c script/function.c \ + script/lexer.c kern/handler.c kern/err.c kern/parser.c \ + kern/list.c kern/misc.c kern/env.c kern/command.c \ + grub_script_check_init.c grub_script.tab.c grub_script.yy.c grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS) MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst diff --git a/conf/tests.rmk b/conf/tests.rmk index 9144e5528..8af4207b7 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -74,6 +74,9 @@ grub_script_comments_SOURCES = tests/grub_script_comments.in check_SCRIPTS += grub_script_functions grub_script_functions_SOURCES = tests/grub_script_functions.in +check_SCRIPTS += grub_script_break +grub_script_break_SOURCES = tests/grub_script_break.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -91,6 +94,7 @@ SCRIPTED_TESTS += grub_script_final_semicolon SCRIPTED_TESTS += grub_script_dollar SCRIPTED_TESTS += grub_script_comments SCRIPTED_TESTS += grub_script_functions +SCRIPTED_TESTS += grub_script_break # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 730aa3005..aee0a743f 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -23,6 +23,7 @@ #include #include #include +#include struct grub_script_mem; @@ -308,6 +309,9 @@ 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); +/* Break command for loops. */ +grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]); + /* This variable points to the parsed command. This is used to communicate with the bison code. */ extern struct grub_script_cmd *grub_script_parsed; diff --git a/script/execute.c b/script/execute.c index 571b6785b..1f639e00b 100644 --- a/script/execute.c +++ b/script/execute.c @@ -30,8 +30,29 @@ is sizeof (int) * 3, and one extra for a possible -ve sign. */ #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) +static unsigned long active_loops; +static unsigned long active_breaks; static struct grub_script_scope *scope = 0; +grub_err_t +grub_script_break (grub_command_t cmd __attribute__((unused)), + int argc, char *argv[]) +{ + char *p = 0; + unsigned long count; + + if (argc == 0) + count = 1; + + else if ((argc > 1) || + (count = grub_strtoul (argv[0], &p, 10)) > active_loops || + (*p != '\0')) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break"); + + active_breaks = count; + return GRUB_ERR_NONE; +} + static char * grub_script_env_get (const char *name) { @@ -242,8 +263,10 @@ grub_err_t grub_script_function_call (grub_script_function_t func, int argc, char **args) { grub_err_t ret = 0; + unsigned long loops = active_loops; struct grub_script_scope new_scope; + active_loops = 0; new_scope.argc = argc; new_scope.args = args; grub_list_push (GRUB_AS_LIST_P (&scope), GRUB_AS_LIST (&new_scope)); @@ -251,6 +274,7 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args) ret = grub_script_execute (func->func); grub_list_pop (GRUB_AS_LIST_P (&scope)); + active_loops = loops; return ret; } @@ -338,7 +362,7 @@ grub_script_execute_cmdlist (struct grub_script_cmd *list) struct grub_script_cmd *cmd; /* Loop over every command and execute it. */ - for (cmd = list->next; cmd; cmd = cmd->next) + for (cmd = list->next; cmd && ! active_breaks; cmd = cmd->next) ret = grub_script_execute_cmd (cmd); return ret; @@ -380,14 +404,22 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) if (!args) return grub_errno; + active_loops++; result = 0; for (i = 0; i < argcount; i++) { - grub_script_env_set (cmdfor->name->str, args[i]); - result = grub_script_execute_cmd (cmdfor->list); + if (! active_breaks) + { + grub_script_env_set (cmdfor->name->str, args[i]); + result = grub_script_execute_cmd (cmdfor->list); + } grub_free (args[i]); } + if (active_breaks) + active_breaks--; + + active_loops--; grub_free (args); return result; } @@ -400,6 +432,7 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd) int result; struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd; + active_loops++; result = 0; do { cond = grub_script_execute_cmd (cmdwhile->cond); @@ -407,8 +440,16 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd) break; result = grub_script_execute_cmd (cmdwhile->list); + + if (active_breaks) + { + active_breaks--; + break; + } + } while (1); /* XXX Put a check for ^C here */ + active_loops--; return result; } diff --git a/script/main.c b/script/main.c index b5159dc7d..c30df1f2d 100644 --- a/script/main.c +++ b/script/main.c @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -49,6 +50,8 @@ static struct grub_parser grub_sh_parser = GRUB_MOD_INIT(sh) { grub_parser_register ("grub", &grub_sh_parser); + grub_register_command ("break", grub_script_break, + N_("[n]"), N_("Exit from loops")); } GRUB_MOD_FINI(sh) diff --git a/tests/grub_script_break.in b/tests/grub_script_break.in new file mode 100644 index 000000000..bf265e8b3 --- /dev/null +++ b/tests/grub_script_break.in @@ -0,0 +1,86 @@ +#! @builddir@/grub-shell-tester +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# break without any arguments +for i in 1 2 3 4 5 6 7 8 9 10 +do + echo $i + if test "$i" = 5 + then + break + fi +done + +# break with one +for i in 1 2 3 4 5 6 7 8 9 10 +do + echo $i + if test "$i" = 5 + then + break 1 + fi +done + +# break with loop count +for i in 1 2 3 4 5 +do + for j in a b c d e f + do + echo "$i $j" + if test "$i" = 3 + then + if test "$j" = d + then + break 2 + fi + fi + done +done + +# break into middle loop +for i in 1 2 3 4 5 +do + for j in a b c d e f + do + echo "$i $j" + if test "$i" = 3 + then + if test "$j" = d + then + break 1 + fi + fi + done +done + +# while and until loops +a= +while test "$a" != "aaaaaaa" +do + a="a$a" + for i in 1 2 3 4 + do + b= + until test "$b" = "bbbbb" + do + b="b$b" + echo "$a $i $b" + if test "$i" = 3; then echo "break 2"; break 2; fi + done + done +done + diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 3b7ab295d..972a5fe17 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -57,6 +57,14 @@ grub_refresh (void) fflush (stdout); } +grub_err_t +grub_script_break (grub_command_t cmd __attribute__((unused)), + int argc __attribute__((unused)), + char *argv[] __attribute__((unused))) +{ + return 0; +} + char * grub_script_execute_argument_to_string (struct grub_script_arg *arg __attribute__ ((unused))) { From eee25941042302c182be4732194c4e2570461490 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 5 May 2010 16:19:31 +0530 Subject: [PATCH 171/503] continue command support --- conf/tests.rmk | 4 ++ script/execute.c | 20 +++++--- script/main.c | 2 + tests/grub_script_continue.in | 86 +++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 tests/grub_script_continue.in diff --git a/conf/tests.rmk b/conf/tests.rmk index 8af4207b7..57cae95c5 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -77,6 +77,9 @@ grub_script_functions_SOURCES = tests/grub_script_functions.in check_SCRIPTS += grub_script_break grub_script_break_SOURCES = tests/grub_script_break.in +check_SCRIPTS += grub_script_continue +grub_script_continue_SOURCES = tests/grub_script_continue.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -95,6 +98,7 @@ SCRIPTED_TESTS += grub_script_dollar SCRIPTED_TESTS += grub_script_comments SCRIPTED_TESTS += grub_script_functions SCRIPTED_TESTS += grub_script_break +SCRIPTED_TESTS += grub_script_continue # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/script/execute.c b/script/execute.c index 1f639e00b..88d15495c 100644 --- a/script/execute.c +++ b/script/execute.c @@ -30,13 +30,13 @@ is sizeof (int) * 3, and one extra for a possible -ve sign. */ #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) +static unsigned long is_continue; static unsigned long active_loops; static unsigned long active_breaks; static struct grub_script_scope *scope = 0; grub_err_t -grub_script_break (grub_command_t cmd __attribute__((unused)), - int argc, char *argv[]) +grub_script_break (grub_command_t cmd, int argc, char *argv[]) { char *p = 0; unsigned long count; @@ -50,6 +50,8 @@ grub_script_break (grub_command_t cmd __attribute__((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break"); active_breaks = count; + is_continue = grub_strcmp (cmd->name, "break") ? 1 : 0; + return GRUB_ERR_NONE; } @@ -408,6 +410,9 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) result = 0; for (i = 0; i < argcount; i++) { + if (is_continue && active_breaks == 1) + active_breaks = 0; + if (! active_breaks) { grub_script_env_set (cmdfor->name->str, args[i]); @@ -441,14 +446,17 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd) result = grub_script_execute_cmd (cmdwhile->list); + if (active_breaks == 1 && is_continue) + active_breaks = 0; + if (active_breaks) - { - active_breaks--; - break; - } + break; } while (1); /* XXX Put a check for ^C here */ + if (active_breaks) + active_breaks--; + active_loops--; return result; } diff --git a/script/main.c b/script/main.c index c30df1f2d..401456e1d 100644 --- a/script/main.c +++ b/script/main.c @@ -52,6 +52,8 @@ GRUB_MOD_INIT(sh) grub_parser_register ("grub", &grub_sh_parser); grub_register_command ("break", grub_script_break, N_("[n]"), N_("Exit from loops")); + grub_register_command ("continue", grub_script_break, + N_("[n]"), N_("Continue loops")); } GRUB_MOD_FINI(sh) diff --git a/tests/grub_script_continue.in b/tests/grub_script_continue.in new file mode 100644 index 000000000..4c28ce404 --- /dev/null +++ b/tests/grub_script_continue.in @@ -0,0 +1,86 @@ +#! @builddir@/grub-shell-tester +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# continue without any arguments +for i in 1 2 3 4 5 6 7 8 9 10 +do + if test "$i" = 5 + then + continue + fi + echo $i +done + +# continue with one +for i in 1 2 3 4 5 6 7 8 9 10 +do + if test "$i" = 5 + then + continue 1 + fi + echo $i +done + +# continue with loop count +for i in 1 2 3 4 5 +do + for j in a b c d e f + do + if test "$i" = 3 + then + if test "$j" = d + then + continue 2 + fi + echo "$i $j" + fi + done +done + +# continue into middle loop +for i in 1 2 3 4 5 +do + for j in a b c d e f + do + if test "$i" = 3 + then + if test "$j" = d + then + continue 1 + fi + echo "$i $j" + fi + done +done + +# while and until loops +a= +while test "$a" != "aaaaaaa" +do + a="a$a" + for i in 1 2 3 4 + do + b= + until test "$b" = "bbbbb" + do + b="b$b" + if test "$i" = 3; then echo "continue 2"; continue 2; fi + echo "$a $i $b" + done + done +done + From da6e6f17f32680314c57f37fd98ce8e836c9bbed Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 6 May 2010 08:45:39 +0530 Subject: [PATCH 172/503] cygwin emu build fixes --- bus/usb/emu/usb.c | 4 ++-- conf/any-emu.rmk | 2 +- include/grub/emu/misc.h | 7 +++++++ kern/emu/getroot.c | 9 ++------- kern/emu/misc.c | 20 ++++++++++++++++++++ util/misc.c | 26 -------------------------- 6 files changed, 32 insertions(+), 36 deletions(-) diff --git a/bus/usb/emu/usb.c b/bus/usb/emu/usb.c index a687eea9b..187857b5b 100644 --- a/bus/usb/emu/usb.c +++ b/bus/usb/emu/usb.c @@ -105,14 +105,14 @@ grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused))) 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_uint16_t idx, 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) + value, idx, data, size, 20) < 0) { usb_close (devh); return GRUB_USB_ERR_STALL; diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index cb0ec873f..3f0df06aa 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ \ gnulib/progname.c disk/host.c kernel_img_HEADERS += datetime.h emu/misc.h -kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib +kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-char-subscripts -Wno-unused -Wno-deprecated-declarations -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 146e64aa9..e037e6be7 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -4,6 +4,13 @@ #include #include +#ifdef __CYGWIN__ +# include +# include +# include +# define DEV_CYGDRIVE_MAJOR 98 +#endif + #ifdef __NetBSD__ /* NetBSD uses /boot for its boot block. */ # define DEFAULT_DIRECTORY "/grub" diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 10a65aa87..6875044da 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -27,13 +29,6 @@ #include #include -#ifdef __CYGWIN__ -# include -# include -# include -# define DEV_CYGDRIVE_MAJOR 98 -#endif - #ifdef __GNU__ #include #include diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 56195a851..4888f4a6b 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -176,6 +176,26 @@ grub_get_rtc (void) * GRUB_TICKS_PER_SECOND / 1000000)); } +#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]; + if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) + grub_util_error ("cygwin_conv_path() failed"); + + int len = strlen (winpath); + int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); + + int i; + for (i = offs; i < len; i++) + if (winpath[i] == '\\') + winpath[i] = '/'; + return xstrdup (winpath + offs); +} +#endif /* This function never prints trailing slashes (so that its output can be appended a slash unconditionally). */ diff --git a/util/misc.c b/util/misc.c index 1656d6b5b..6785eb00f 100644 --- a/util/misc.c +++ b/util/misc.c @@ -53,11 +53,6 @@ # include #endif -#ifdef __CYGWIN__ -# include -# define DEV_CYGDRIVE_MAJOR 98 -#endif - #ifdef __MINGW32__ #include #include @@ -304,27 +299,6 @@ canonicalize_file_name (const char *path) return ret; } -#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]; - if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) - grub_util_error ("cygwin_conv_path() failed"); - - int len = strlen (winpath); - int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); - - int i; - for (i = offs; i < len; i++) - if (winpath[i] == '\\') - winpath[i] = '/'; - return xstrdup (winpath + offs); -} -#endif - #ifdef GRUB_UTIL void grub_util_init_nls (void) From ab4da2cd366dbd9b36542f8870c4a42adccc6df1 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 6 May 2010 09:33:45 +0530 Subject: [PATCH 173/503] build fixes for real platforms --- conf/i386-pc.rmk | 37 ++++++++++++------------- conf/i386-qemu.rmk | 2 +- conf/mips.rmk | 2 +- conf/sparc64-ieee1275.rmk | 44 +++++++++++++++--------------- conf/x86-efi.rmk | 2 +- util/i386/pc/grub-setup.c | 6 ++-- util/sparc64/ieee1275/grub-setup.c | 4 +-- 7 files changed, 48 insertions(+), 49 deletions(-) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index a5a1b08ea..abefb4d84 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -67,30 +67,29 @@ sbin_UTILITIES = grub-setup # For grub-mkimage. grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c + kern/emu/misc.c util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h -grub_setup_SOURCES = gnulib/progname.c \ - 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 kern/list.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/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ - fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ - fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ - \ - partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ - partmap/gpt.c \ - \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c util/mm.c \ +grub_setup_SOURCES = gnulib/progname.c util/i386/pc/grub-setup.c \ + util/misc.c kern/emu/misc.c kern/emu/getroot.c \ + kern/emu/hostdisk.c kern/device.c kern/disk.c kern/err.c \ + kern/misc.c kern/parser.c kern/partition.c kern/file.c \ + kern/emu/mm.c kern/fs.c kern/env.c kern/list.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/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ + \ + partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ + partmap/gpt.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + util/raid.c util/lvm.c \ grub_setup_init.c sbin_SCRIPTS += grub-install diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 664bef12a..d5a18a78c 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -14,7 +14,7 @@ boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LI boot_img_FORMAT = binary bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c kern/emu/misc.c \ util/resolve.c gnulib/progname.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile diff --git a/conf/mips.rmk b/conf/mips.rmk index 4603c219e..6e13ace29 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -13,7 +13,7 @@ bin_SCRIPTS = # For grub-mkimage. bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c + kern/emu/misc.c util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) util/grub-mkrawimage.c_DEPENDENCIES = Makefile diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index f0c9b0db7..99128f918 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -44,34 +44,34 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname # For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c kern/emu/misc.c \ util/resolve.c gnulib/progname.c # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h -grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ - util/ieee1275/ofpath.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 kern/list.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/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ - fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ - fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ - \ - partmap/amiga.c partmap/apple.c partmap/msdos.c \ - partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ - \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c util/mm.c gnulib/progname.c \ - grub_setup_init.c +grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c \ + util/ieee1275/ofpath.c util/misc.c kern/emu/hostdisk.c \ + kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.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 kern/list.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/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ + \ + partmap/amiga.c partmap/apple.c partmap/msdos.c \ + partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c util/raid.c \ + util/lvm.c gnulib/progname.c grub_setup_init.c # For grub-ofpathname. -grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ - util/ieee1275/ofpath.c util/misc.c gnulib/progname.c +grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ + util/ieee1275/ofpath.c util/misc.c kern/emu/misc.c \ + gnulib/progname.c # Scripts. sbin_SCRIPTS = grub-install diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index e29dad645..7d7d9a3e1 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -5,7 +5,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ - util/misc.c util/resolve.c + util/misc.c kern/emu/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile # Scripts. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..be6224f7f 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -28,14 +28,14 @@ #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; @@ -423,7 +423,7 @@ unable_to_embed: /* Make sure that GRUB reads the identical image as the OS. */ tmp_img = xmalloc (core_size); core_path_dev_full = grub_util_get_path (dir, core_file); - core_path_dev = make_system_path_relative_to_its_root (core_path_dev_full); + core_path_dev = grub_make_system_path_relative_to_its_root (core_path_dev_full); free (core_path_dev_full); /* It is a Good Thing to sync two times. */ diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 06bc16795..a46a22f87 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -46,7 +46,7 @@ #include #include #include -#include +#include #define _GNU_SOURCE 1 #include From 8f6a910b2389271059858ff58cace5a0639472c8 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 6 May 2010 09:55:06 +0530 Subject: [PATCH 174/503] fixed n > active_loops case --- include/grub/misc.h | 9 +++++++++ script/execute.c | 5 ++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/grub/misc.h b/include/grub/misc.h index 9bfc6974e..bcbcf33a3 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -281,6 +281,15 @@ grub_abs (int x) return (unsigned int) x; } +static inline long +grub_min (long x, long y) +{ + if (x < y) + return x; + else + return y; +} + static inline long grub_max (long x, long y) { diff --git a/script/execute.c b/script/execute.c index 1f639e00b..3ad0b9dff 100644 --- a/script/execute.c +++ b/script/execute.c @@ -44,12 +44,11 @@ grub_script_break (grub_command_t cmd __attribute__((unused)), if (argc == 0) count = 1; - else if ((argc > 1) || - (count = grub_strtoul (argv[0], &p, 10)) > active_loops || + else if ((argc > 1) || (count = grub_strtoul (argv[0], &p, 10)) == 0 || (*p != '\0')) return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break"); - active_breaks = count; + active_breaks = grub_min (active_loops, count); return GRUB_ERR_NONE; } From 60b4a7c45be55b950761bca55475a01a2307b946 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 6 May 2010 10:16:55 +0530 Subject: [PATCH 175/503] sparc build fix --- util/sparc64/ieee1275/grub-setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index a46a22f87..a758b42e3 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -627,8 +627,8 @@ main (int argc, char *argv[]) find_dest_dev (&ginfo, argv); - ginfo.prefix = make_system_path_relative_to_its_root (ginfo.dir ? - : DEFAULT_DIRECTORY); + ginfo.prefix = grub_make_system_path_relative_to_its_root (ginfo.dir ? + : DEFAULT_DIRECTORY); check_root_dev (&ginfo); From e903ddec1c9f898068295d8781b1fbb295721d48 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 6 May 2010 21:11:59 +0200 Subject: [PATCH 176/503] move ANSI code recognition to terminfo.mod --- conf/common.rmk | 5 +- conf/i386-ieee1275.rmk | 1 + conf/powerpc-ieee1275.rmk | 2 +- conf/sparc64-ieee1275.rmk | 3 +- include/grub/terminfo.h | 3 + term/ieee1275/ofconsole.c | 122 +++++--------------------------------- term/terminfo.c | 109 ++++++++++++++++++++++++++++++++++ 7 files changed, 136 insertions(+), 109 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index a1a39d723..3e22678ad 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -465,7 +465,7 @@ scsi_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \ ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \ configfile.mod echo.mod \ - terminfo.mod test.mod blocklist.mod hexdump.mod \ + test.mod blocklist.mod hexdump.mod \ read.mod sleep.mod loadenv.mod crc.mod parttool.mod \ msdospart.mod memrw.mod normal.mod sh.mod \ gptsync.mod true.mod probe.mod password.mod \ @@ -596,10 +596,13 @@ configfile_mod_SOURCES = commands/configfile.c configfile_mod_CFLAGS = $(COMMON_CFLAGS) configfile_mod_LDFLAGS = $(COMMON_LDFLAGS) +ifneq ($(platform), ieee1275) # For terminfo.mod. +pkglib_MODULES += terminfo.mod terminfo_mod_SOURCES = term/terminfo.c term/tparm.c terminfo_mod_CFLAGS = $(COMMON_CFLAGS) terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS) +endif # For blocklist.mod. blocklist_mod_SOURCES = commands/blocklist.c diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 05ba38a65..648205657 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -22,6 +22,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \ kern/generic/millisleep.c \ kern/ieee1275/ieee1275.c \ term/ieee1275/ofconsole.c \ + term/terminfo.c term/tparm.c \ disk/ieee1275/ofdisk.c \ symlist.c kernel_img_HEADERS += ieee1275/ieee1275.h diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index d5968ac8e..cd08770df 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ kern/ieee1275/init.c \ kern/ieee1275/mmap.c \ - term/ieee1275/ofconsole.c \ + term/ieee1275/ofconsole.c term/terminfo.c term/tparm.c \ kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 49834a1fd..6fd7d0032 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -30,7 +30,8 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/sparc64/ieee1275/init.c \ kern/ieee1275/mmap.c \ term/ieee1275/ofconsole.c \ - kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ + kern/ieee1275/openfw.c term/terminfo.c term/tparm.c \ + disk/ieee1275/ofdisk.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index e3a2c170a..84a6f6ab2 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -34,4 +34,7 @@ void grub_terminfo_reverse_video_off (grub_term_output_t oterm); void grub_terminfo_cursor_on (grub_term_output_t oterm); void grub_terminfo_cursor_off (grub_term_output_t oterm); +#define GRUB_TERMINFO_READKEY_MAX_LEN 4 +void grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void)); + #endif /* ! GRUB_TERMINFO_HEADER */ diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index ce587d491..74de5806e 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,7 @@ static grub_uint8_t grub_ofconsole_height; static int grub_curr_x; static int grub_curr_y; -static int grub_keybuf; +static int grub_keybuf[GRUB_TERMINFO_READKEY_MAX_LEN]; static int grub_buflen; struct color @@ -149,116 +150,28 @@ grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_col *highlight_color = grub_ofconsole_highlight_color; } -#define ANSI_C0 0x9b - static int -grub_ofconsole_readkey (int *key) +readkey (void) { grub_uint8_t c; grub_ssize_t actual = 0; grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); if (actual > 0) - switch(c) - { - case 0x7f: - /* Backspace: Ctrl-h. */ - c = '\b'; - break; - case ANSI_C0: - case '\e': - { - grub_uint64_t start; - - if (c == '\e') - { - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - /* On 9600 we have to wait up to 12 milliseconds. */ - start = grub_get_time_ms (); - while (actual <= 0 && grub_get_time_ms () - start < 12) - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - if (actual <= 0) - { - *key = '\e'; - return 1; - } - - if (c != '[') - return 0; - } - - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - /* On 9600 we have to wait up to 12 milliseconds. */ - start = grub_get_time_ms (); - while (actual <= 0 && grub_get_time_ms () - start < 12) - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - if (actual <= 0) - return 0; - - switch (c) - { - case 'A': - /* Up: Ctrl-p. */ - c = GRUB_TERM_UP; - break; - case 'B': - /* Down: Ctrl-n. */ - c = GRUB_TERM_DOWN; - break; - case 'C': - /* Right: Ctrl-f. */ - c = GRUB_TERM_RIGHT; - break; - case 'D': - /* Left: Ctrl-b. */ - c = GRUB_TERM_LEFT; - break; - case '3': - { - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - /* On 9600 we have to wait up to 12 milliseconds. */ - start = grub_get_time_ms (); - while (actual <= 0 && grub_get_time_ms () - start < 12) - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - if (actual <= 0) - return 0; - - /* Delete: Ctrl-d. */ - if (c == '~') - c = GRUB_TERM_DC; - else - return 0; - break; - } - break; - } - } - } - - *key = c; - return actual > 0; + return c; + return -1; } 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; - } + grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey); + + if (grub_buflen) + return 1; return -1; } @@ -266,17 +179,14 @@ grub_ofconsole_checkkey (void) static int grub_ofconsole_getkey (void) { - int key; + int ret; + while (! grub_buflen) + grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey); - if (grub_buflen) - { - grub_buflen =0; - return grub_keybuf; - } - - while (! grub_ofconsole_readkey (&key)); - - return key; + ret = grub_keybuf[0]; + grub_buflen--; + grub_memmove (grub_keybuf, grub_keybuf + 1, grub_buflen); + return ret; } static grub_uint16_t diff --git a/term/terminfo.c b/term/terminfo.c index 03a7dc2b6..ef713e151 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -32,6 +32,7 @@ #include #include #include +#include struct terminfo { @@ -167,6 +168,114 @@ grub_terminfo_cursor_off (grub_term_output_t oterm) putstr (grub_terminfo_tparm (term.cursor_off), oterm); } +#define ANSI_C0 0x9b + +void +grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void)) +{ + int c; + +#define CONTINUE_READ \ + { \ + grub_uint64_t start; \ + /* On 9600 we have to wait up to 12 milliseconds. */ \ + start = grub_get_time_ms (); \ + do \ + c = readkey (); \ + while (c == -1 && grub_get_time_ms () - start < 12); \ + if (c == -1) \ + return; \ + \ + keys[*len] = c; \ + (*len)++; \ + } + + c = readkey (); + if (c < 0) + { + *len = 0; + return; + } + *len = 1; + keys[0] = c; + if (c != ANSI_C0 && c != '\e') + { + /* Backspace: Ctrl-h. */ + if (c == 0x7f) + c = '\b'; + *len = 1; + keys[0] = c; + return; + } + + { + static struct + { + char key; + char ascii; + } + three_code_table[] = + { + {'4', GRUB_TERM_DC}, + {'A', GRUB_TERM_UP}, + {'B', GRUB_TERM_DOWN}, + {'C', GRUB_TERM_RIGHT}, + {'D', GRUB_TERM_LEFT}, + {'F', GRUB_TERM_END}, + {'H', GRUB_TERM_HOME}, + {'K', GRUB_TERM_END}, + {'P', GRUB_TERM_DC}, + {'?', GRUB_TERM_PPAGE}, + {'/', GRUB_TERM_NPAGE} + }; + + static struct + { + char key; + char ascii; + } + four_code_table[] = + { + {'1', GRUB_TERM_HOME}, + {'3', GRUB_TERM_DC}, + {'5', GRUB_TERM_PPAGE}, + {'6', GRUB_TERM_NPAGE} + }; + unsigned i; + + if (c == '\e') + { + CONTINUE_READ; + + if (c != '[') + return; + } + + CONTINUE_READ; + + for (i = 0; i < ARRAY_SIZE (three_code_table); i++) + if (three_code_table[i].key == c) + { + keys[0] = three_code_table[i].ascii; + *len = 1; + return; + } + + for (i = 0; i < ARRAY_SIZE (four_code_table); i++) + if (four_code_table[i].key == c) + { + CONTINUE_READ; + if (c != '~') + return; + keys[0] = three_code_table[i].ascii; + *len = 1; + return; + } + return; + } +#undef CONTINUE_READ +} + /* GRUB Command. */ static grub_err_t From 82e32bc310045899af6bd13399d0dcc4c5f9583d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 6 May 2010 21:32:58 +0200 Subject: [PATCH 177/503] make serial use ANSI code recognition in terminfo.mod --- conf/i386-ieee1275.rmk | 2 +- include/grub/terminfo.h | 20 +++--- term/ieee1275/ofconsole.c | 4 +- term/serial.c | 125 ++++++-------------------------------- 4 files changed, 30 insertions(+), 121 deletions(-) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 648205657..66e75c77b 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -25,7 +25,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \ term/terminfo.c term/tparm.c \ disk/ieee1275/ofdisk.c \ symlist.c -kernel_img_HEADERS += ieee1275/ieee1275.h +kernel_img_HEADERS += ieee1275/ieee1275.h terminfo.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 84a6f6ab2..f078871d0 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -23,18 +23,18 @@ #include #include -char *grub_terminfo_get_current (void); -grub_err_t grub_terminfo_set_current (const char *); +char *EXPORT_FUNC(grub_terminfo_get_current) (void); +grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (const char *); -void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, - grub_term_output_t oterm); -void grub_terminfo_cls (grub_term_output_t oterm); -void grub_terminfo_reverse_video_on (grub_term_output_t oterm); -void grub_terminfo_reverse_video_off (grub_term_output_t oterm); -void grub_terminfo_cursor_on (grub_term_output_t oterm); -void grub_terminfo_cursor_off (grub_term_output_t oterm); +void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_uint8_t x, grub_uint8_t y, + grub_term_output_t oterm); +void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t oterm); +void EXPORT_FUNC(grub_terminfo_reverse_video_on) (grub_term_output_t oterm); +void EXPORT_FUNC(grub_terminfo_reverse_video_off) (grub_term_output_t oterm); +void EXPORT_FUNC(grub_terminfo_cursor_on) (grub_term_output_t oterm); +void EXPORT_FUNC(grub_terminfo_cursor_off) (grub_term_output_t oterm); #define GRUB_TERMINFO_READKEY_MAX_LEN 4 -void grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void)); +void EXPORT_FUNC(grub_terminfo_readkey) (int *keys, int *len, int (*readkey) (void)); #endif /* ! GRUB_TERMINFO_HEADER */ diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 74de5806e..b9b60901b 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -166,12 +166,12 @@ static int grub_ofconsole_checkkey (void) { if (grub_buflen) - return 1; + return grub_keybuf[0]; grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey); if (grub_buflen) - return 1; + return grub_keybuf[0]; return -1; } diff --git a/term/serial.c b/term/serial.c index 6a20545b2..bdc80cb74 100644 --- a/term/serial.c +++ b/term/serial.c @@ -35,8 +35,8 @@ static unsigned int keep_track = 1; static unsigned int registered = 0; /* An input buffer. */ -static char input_buf[8]; -static unsigned int npending = 0; +static int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN]; +static int npending = 0; static struct grub_term_output grub_serial_term_output; @@ -114,98 +114,6 @@ serial_hw_put (const int c) grub_outb (c, serial_settings.port + UART_TX); } -static void -serial_translate_key_sequence (void) -{ - unsigned int i; - 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} - }; - - if (npending < 3) - return; - - /* The buffer must start with "ESC [". */ - if (input_buf[0] != '\e' || input_buf[1] != '[') - return; - - for (i = 0; i < ARRAY_SIZE (three_code_table); 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) - { - short key = input_buf[3] | (input_buf[4] << 8); - - for (i = 0; i < ARRAY_SIZE (four_code_table); 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) @@ -248,28 +156,29 @@ serial_get_divisor (unsigned int speed) static int grub_serial_checkkey (void) { - if (fill_input_buf (1)) + if (npending) return input_buf[0]; - else - return -1; + + grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch); + + if (npending) + return input_buf[0]; + + return -1; } /* The serial version of getkey. */ static int grub_serial_getkey (void) { - int c; + int ret; + while (! npending) + grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch); - while (! fill_input_buf (0)) - ; - - c = input_buf[0]; - if (c == 0x7f) - c = GRUB_TERM_BACKSPACE; - - grub_memmove (input_buf, input_buf + 1, --npending); - - return c; + ret = input_buf[0]; + npending--; + grub_memmove (input_buf, input_buf + 1, npending); + return ret; } /* Initialize a serial device. PORT is the port number for a serial device. From 58664b94b78de229970f97acd40fc1a358934bec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 7 May 2010 02:30:44 +0200 Subject: [PATCH 178/503] pass pointer to term to term functions --- commands/terminal.c | 12 +++--- include/grub/i386/pc/console.h | 16 ++++---- include/grub/i386/vga_common.h | 13 ++++-- include/grub/term.h | 72 +++++++++++++++++++--------------- kern/i386/pc/startup.S | 8 ++-- kern/term.c | 14 +++---- normal/term.c | 16 ++++---- term/at_keyboard.c | 8 ++-- term/efi/console.c | 30 ++++++++------ term/gfxterm.c | 46 +++++++++++++--------- term/i386/pc/console.c | 2 +- term/i386/pc/vga.c | 25 +++++++----- term/i386/pc/vga_text.c | 19 +++++---- term/i386/vga_common.c | 11 ++++-- term/ieee1275/ofconsole.c | 47 +++++++++++----------- term/serial.c | 26 ++++++------ term/terminfo.c | 2 +- term/usb_keyboard.c | 8 ++-- util/console.c | 36 ++++++++++------- 19 files changed, 230 insertions(+), 181 deletions(-) diff --git a/commands/terminal.c b/commands/terminal.c index 1129c39bd..d34602a1b 100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@ -30,8 +30,8 @@ struct abstract_terminal { struct abstract_terminal *next; const char *name; - grub_err_t (*init) (void); - grub_err_t (*fini) (void); + grub_err_t (*init) (struct abstract_terminal *term); + grub_err_t (*fini) (struct abstract_terminal *term); }; static grub_err_t @@ -123,7 +123,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, break; if (term) { - if (term->init && term->init () != GRUB_ERR_NONE) + if (term->init && term->init (term) != GRUB_ERR_NONE) return grub_errno; grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); @@ -147,7 +147,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, "can't remove the last terminal"); grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); if (term->fini) - term->fini (); + term->fini (term); grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); } } @@ -160,7 +160,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, break; if (term) { - if (term->init && term->init () != GRUB_ERR_NONE) + if (term->init && term->init (term) != GRUB_ERR_NONE) return grub_errno; grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); @@ -183,7 +183,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, "can't remove the last terminal"); grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); if (term->fini) - term->fini (); + term->fini (term); grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); } } diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index b677bb886..7f58344ec 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -40,13 +40,15 @@ #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); -void grub_console_putchar (const struct grub_unicode_glyph *c); +int grub_console_checkkey (struct grub_term_input *term); +int grub_console_getkey (struct grub_term_input *term); +grub_uint16_t grub_console_getxy (struct grub_term_output *term); +void grub_console_gotoxy (struct grub_term_output *term, + grub_uint8_t x, grub_uint8_t y); +void grub_console_cls (struct grub_term_output *term); +void grub_console_setcursor (struct grub_term_output *term, int on); +void grub_console_putchar (struct grub_term_output *term, + const struct grub_unicode_glyph *c); /* Initialize the console system. */ void grub_console_init (void); diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h index 7df2b9e9e..8ba09dfea 100644 --- a/include/grub/i386/vga_common.h +++ b/include/grub/i386/vga_common.h @@ -25,9 +25,14 @@ extern grub_uint8_t grub_console_cur_color; -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); +grub_uint16_t grub_console_getwh (struct grub_term_output *term); +void grub_console_setcolorstate (struct grub_term_output *term, + grub_term_color_state state); +void grub_console_setcolor (struct grub_term_output *term, + grub_uint8_t normal_color, + grub_uint8_t highlight_color); +void grub_console_getcolor (struct grub_term_output *term, + grub_uint8_t *normal_color, + grub_uint8_t *highlight_color); #endif /* ! GRUB_VGA_COMMON_CPU_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h index 40f7fb0b9..c43eb6ff7 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -136,19 +136,21 @@ struct grub_term_input const char *name; /* Initialize the terminal. */ - grub_err_t (*init) (void); + grub_err_t (*init) (struct grub_term_input *term); /* Clean up the terminal. */ - grub_err_t (*fini) (void); + grub_err_t (*fini) (struct grub_term_input *term); /* Check if any input character is available. */ - int (*checkkey) (void); + int (*checkkey) (struct grub_term_input *term); /* Get a character. */ - int (*getkey) (void); + int (*getkey) (struct grub_term_input *term); /* Get keyboard modifier status. */ - int (*getkeystatus) (void); + int (*getkeystatus) (struct grub_term_input *term); + + void *data; }; typedef struct grub_term_input *grub_term_input_t; @@ -161,49 +163,57 @@ struct grub_term_output const char *name; /* Initialize the terminal. */ - grub_err_t (*init) (void); + grub_err_t (*init) (struct grub_term_output *term); /* Clean up the terminal. */ - grub_err_t (*fini) (void); + grub_err_t (*fini) (struct grub_term_output *term); /* Put a character. C is encoded in Unicode. */ - void (*putchar) (const struct grub_unicode_glyph *c); + void (*putchar) (struct grub_term_output *term, + const struct grub_unicode_glyph *c); /* Get the number of columns occupied by a given character C. C is encoded in Unicode. */ - grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *c); + grub_ssize_t (*getcharwidth) (struct grub_term_output *term, + const struct grub_unicode_glyph *c); /* Get the screen size. The return value is ((Width << 8) | Height). */ - grub_uint16_t (*getwh) (void); + grub_uint16_t (*getwh) (struct grub_term_output *term); /* Get the cursor position. The return value is ((X << 8) | Y). */ - grub_uint16_t (*getxy) (void); + grub_uint16_t (*getxy) (struct grub_term_output *term); /* Go to the position (X, Y). */ - void (*gotoxy) (grub_uint8_t x, grub_uint8_t y); + void (*gotoxy) (struct grub_term_output *term, + grub_uint8_t x, grub_uint8_t y); /* Clear the screen. */ - void (*cls) (void); + void (*cls) (struct grub_term_output *term); /* Set the current color to be used */ - void (*setcolorstate) (grub_term_color_state state); + void (*setcolorstate) (struct grub_term_output *term, + 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); + void (*setcolor) (struct grub_term_output *term, + 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); + void (*getcolor) (struct grub_term_output *term, + grub_uint8_t *normal_color, grub_uint8_t *highlight_color); /* Turn on/off the cursor. */ - void (*setcursor) (int on); + void (*setcursor) (struct grub_term_output *term, int on); /* Update the screen. */ - void (*refresh) (void); + void (*refresh) (struct grub_term_output *term); /* The feature flags defined above. */ grub_uint32_t flags; + + void *data; }; typedef struct grub_term_output *grub_term_output_t; @@ -222,7 +232,7 @@ grub_term_register_input (const char *name __attribute__ ((unused)), else { /* If this is the first terminal, enable automatically. */ - if (! term->init || term->init () == GRUB_ERR_NONE) + if (! term->init || term->init (term) == GRUB_ERR_NONE) grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); } } @@ -237,7 +247,7 @@ grub_term_register_output (const char *name __attribute__ ((unused)), else { /* If this is the first terminal, enable automatically. */ - if (! term->init || term->init () == GRUB_ERR_NONE) + if (! term->init || term->init (term) == GRUB_ERR_NONE) grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term)); } @@ -277,12 +287,12 @@ void grub_term_restore_pos (grub_uint16_t *pos); static inline unsigned grub_term_width (struct grub_term_output *term) { - return ((term->getwh()&0xFF00)>>8); + return ((term->getwh(term)&0xFF00)>>8); } static inline unsigned grub_term_height (struct grub_term_output *term) { - return (term->getwh()&0xFF); + return (term->getwh(term)&0xFF); } /* The width of the border. */ @@ -326,20 +336,20 @@ grub_term_cursor_x (struct grub_term_output *term) static inline grub_uint16_t grub_term_getxy (struct grub_term_output *term) { - return term->getxy (); + return term->getxy (term); } static inline void grub_term_refresh (struct grub_term_output *term) { if (term->refresh) - term->refresh (); + term->refresh (term); } static inline void grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y) { - term->gotoxy (x, y); + term->gotoxy (term, x, y); } static inline void @@ -347,7 +357,7 @@ grub_term_setcolorstate (struct grub_term_output *term, grub_term_color_state state) { if (term->setcolorstate) - term->setcolorstate (state); + term->setcolorstate (term, state); } /* Set the normal color and the highlight color. The format of each @@ -357,7 +367,7 @@ grub_term_setcolor (struct grub_term_output *term, grub_uint8_t normal_color, grub_uint8_t highlight_color) { if (term->setcolor) - term->setcolor (normal_color, highlight_color); + term->setcolor (term, normal_color, highlight_color); } /* Turn on/off the cursor. */ @@ -365,14 +375,14 @@ static inline void grub_term_setcursor (struct grub_term_output *term, int on) { if (term->setcursor) - term->setcursor (on); + term->setcursor (term, on); } static inline void grub_term_cls (struct grub_term_output *term) { if (term->cls) - (term->cls) (); + (term->cls) (term); else { grub_putcode ('\n', term); @@ -402,7 +412,7 @@ grub_term_getcharwidth (struct grub_term_output *term, const struct grub_unicode_glyph *c) { if (term->getcharwidth) - return term->getcharwidth (c); + return term->getcharwidth (term, c); else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL) || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) @@ -419,7 +429,7 @@ grub_term_getcolor (struct grub_term_output *term, grub_uint8_t *normal_color, grub_uint8_t *highlight_color) { if (term->getcolor) - term->getcolor (normal_color, highlight_color); + term->getcolor (term, normal_color, highlight_color); else { *normal_color = 0x07; diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index f3942e199..761eb53fe 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1078,7 +1078,7 @@ xsmap: */ FUNCTION(grub_console_putchar) /* Retrieve the base character. */ - movl 0(%eax), %edx + movl 0(%edx), %edx pusha movb EXT_C(grub_console_cur_color), %bl @@ -1329,8 +1329,8 @@ FUNCTION(grub_console_gotoxy) pushl %ebp pushl %ebx /* save EBX */ - movb %dl, %dh /* %dh = y */ - movb %al, %dl /* %dl = x */ + movb %cl, %dh /* %dh = y */ + /* %dl = x */ call prot_to_real .code16 @@ -1406,7 +1406,7 @@ FUNCTION(grub_console_setcursor) pushl %ebx /* push ON */ - pushl %eax + pushl %edx /* check if the standard cursor shape has already been saved */ movw console_cursor_shape, %ax diff --git a/kern/term.c b/kern/term.c index dba94ecf7..a1f8b9f93 100644 --- a/kern/term.c +++ b/kern/term.c @@ -47,14 +47,14 @@ grub_putcode_dumb (grub_uint32_t code, { int n; - n = 8 - ((term->getxy () >> 8) & 7); + n = 8 - ((term->getxy (term) >> 8) & 7); while (n--) grub_putcode_dumb (' ', term); return; } - (term->putchar) (&c); + (term->putchar) (term, &c); if (code == '\n') grub_putcode_dumb ('\r', term); } @@ -87,9 +87,9 @@ grub_getkey (void) { FOR_ACTIVE_TERM_INPUTS(term) { - int key = term->checkkey (); + int key = term->checkkey (term); if (key != -1) - return term->getkey (); + return term->getkey (term); } grub_cpu_idle (); @@ -103,7 +103,7 @@ grub_checkkey (void) FOR_ACTIVE_TERM_INPUTS(term) { - int key = term->checkkey (); + int key = term->checkkey (term); if (key != -1) return key; } @@ -120,7 +120,7 @@ grub_getkeystatus (void) FOR_ACTIVE_TERM_INPUTS(term) { if (term->getkeystatus) - status |= term->getkeystatus (); + status |= term->getkeystatus (term); } return status; @@ -139,7 +139,7 @@ grub_cls (void) grub_term_refresh (term); } else - (term->cls) (); + (term->cls) (term); } } diff --git a/normal/term.c b/normal/term.c index 97c415f8a..f46930be4 100644 --- a/normal/term.c +++ b/normal/term.c @@ -366,10 +366,10 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) { int n; - n = 8 - ((term->getxy () >> 8) & 7); + n = 8 - ((term->getxy (term) >> 8) & 7); c2.base = ' '; while (n--) - (term->putchar) (&c2); + (term->putchar) (term, &c2); return; } @@ -405,19 +405,19 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) for (ptr = u8; *ptr; ptr++) { c2.base = *ptr; - (term->putchar) (&c2); + (term->putchar) (term, &c2); c2.estimated_width = 0; } } c2.estimated_width = 1; } else - (term->putchar) (c); + (term->putchar) (term, c); if (c->base == '\n') { c2.base = '\r'; - (term->putchar) (&c2); + (term->putchar) (term, &c2); } } @@ -468,7 +468,7 @@ static grub_ssize_t get_startwidth (struct grub_term_output *term, int margin_left) { - return ((term->getxy () >> 8) & 0xff) - margin_left; + return ((term->getxy (term) >> 8) & 0xff) - margin_left; } static int @@ -670,8 +670,8 @@ print_ucs4_real (const grub_uint32_t * str, if (backlog) state = find_term_state (term); - if (((term->getxy () >> 8) & 0xff) < margin_left) - grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff)); + if (((term->getxy (term) >> 8) & 0xff) < margin_left) + grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff)); if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 1f84ae71a..c3e71ea2d 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -236,7 +236,7 @@ grub_at_keyboard_getkey_noblock (void) } static int -grub_at_keyboard_checkkey (void) +grub_at_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused))) { if (pending_key != -1) return 1; @@ -250,7 +250,7 @@ grub_at_keyboard_checkkey (void) } static int -grub_at_keyboard_getkey (void) +grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) { int key; if (pending_key != -1) @@ -267,7 +267,7 @@ grub_at_keyboard_getkey (void) } static grub_err_t -grub_keyboard_controller_init (void) +grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unused))) { pending_key = -1; at_keyboard_status = 0; @@ -277,7 +277,7 @@ grub_keyboard_controller_init (void) } static grub_err_t -grub_keyboard_controller_fini (void) +grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) { grub_keyboard_controller_write (grub_keyboard_controller_orig); return GRUB_ERR_NONE; diff --git a/term/efi/console.c b/term/efi/console.c index cba56bcc8..e5dab8a96 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -85,7 +85,8 @@ map_char (grub_uint32_t c) } static void -grub_console_putchar (const struct grub_unicode_glyph *c) +grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { grub_efi_char16_t str[2 + c->ncomb]; grub_efi_simple_text_output_interface_t *o; @@ -113,7 +114,7 @@ grub_console_putchar (const struct grub_unicode_glyph *c) } static int -grub_console_checkkey (void) +grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused))) { grub_efi_simple_input_interface_t *i; grub_efi_input_key_t key; @@ -208,7 +209,7 @@ grub_console_checkkey (void) } static int -grub_console_getkey (void) +grub_console_getkey (struct grub_term_input *term) { grub_efi_simple_input_interface_t *i; grub_efi_boot_services_t *b; @@ -232,7 +233,7 @@ grub_console_getkey (void) if (status != GRUB_EFI_SUCCESS) return -1; - grub_console_checkkey (); + grub_console_checkkey (term); } while (read_key < 0); @@ -242,7 +243,7 @@ grub_console_getkey (void) } static grub_uint16_t -grub_console_getwh (void) +grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) { grub_efi_simple_text_output_interface_t *o; grub_efi_uintn_t columns, rows; @@ -259,7 +260,7 @@ grub_console_getwh (void) } static grub_uint16_t -grub_console_getxy (void) +grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) { grub_efi_simple_text_output_interface_t *o; @@ -268,7 +269,8 @@ grub_console_getxy (void) } static void -grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y) +grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) { grub_efi_simple_text_output_interface_t *o; @@ -277,7 +279,7 @@ grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y) } static void -grub_console_cls (void) +grub_console_cls (struct grub_term_output *term __attribute__ ((unused))) { grub_efi_simple_text_output_interface_t *o; grub_efi_int32_t orig_attr; @@ -290,7 +292,8 @@ grub_console_cls (void) } static void -grub_console_setcolorstate (grub_term_color_state state) +grub_console_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + grub_term_color_state state) { grub_efi_simple_text_output_interface_t *o; @@ -312,21 +315,24 @@ grub_console_setcolorstate (grub_term_color_state state) } static void -grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) +grub_console_setcolor (struct grub_term_output *term __attribute__ ((unused)), + 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) +grub_console_getcolor (struct grub_term_output *term __attribute__ ((unused)), + 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_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) { grub_efi_simple_text_output_interface_t *o; diff --git a/term/gfxterm.c b/term/gfxterm.c index af6401bbf..d9fb2e04c 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -146,10 +146,11 @@ static unsigned int calculate_normal_character_width (grub_font_t font); static unsigned char calculate_character_width (struct grub_font_glyph *glyph); -static void grub_gfxterm_refresh (void); +static void grub_gfxterm_refresh (struct grub_term_output *term __attribute__ ((unused))); static grub_ssize_t -grub_gfxterm_getcharwidth (const struct grub_unicode_glyph *c); +grub_gfxterm_getcharwidth (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c); static void set_term_color (grub_uint8_t term_color) @@ -364,7 +365,7 @@ grub_gfxterm_fullscreen (void) } static grub_err_t -grub_gfxterm_term_init (void) +grub_gfxterm_term_init (struct grub_term_output *term __attribute__ ((unused))) { char *tmp; grub_err_t err; @@ -408,7 +409,7 @@ destroy_window (void) } static grub_err_t -grub_gfxterm_term_fini (void) +grub_gfxterm_term_fini (struct grub_term_output *term __attribute__ ((unused))) { destroy_window (); grub_video_restore (); @@ -822,7 +823,8 @@ scroll_up (void) } static void -grub_gfxterm_putchar (const struct grub_unicode_glyph *c) +grub_gfxterm_putchar (struct grub_term_output *term, + const struct grub_unicode_glyph *c) { if (c->base == '\a') /* FIXME */ @@ -860,7 +862,7 @@ grub_gfxterm_putchar (const struct grub_unicode_glyph *c) /* Calculate actual character width for glyph. This is number of times of normal_font_width. */ - char_width = grub_gfxterm_getcharwidth (c); + char_width = grub_gfxterm_getcharwidth (term, c); /* If we are about to exceed line length, wrap to next line. */ if (virtual_screen.cursor_x + char_width > virtual_screen.columns) @@ -959,7 +961,8 @@ calculate_character_width (struct grub_font_glyph *glyph) } static grub_ssize_t -grub_gfxterm_getcharwidth (const struct grub_unicode_glyph *c) +grub_gfxterm_getcharwidth (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { int dev_width; dev_width = grub_font_get_constructed_device_width (virtual_screen.font, c); @@ -972,19 +975,20 @@ grub_gfxterm_getcharwidth (const struct grub_unicode_glyph *c) } static grub_uint16_t -grub_virtual_screen_getwh (void) +grub_virtual_screen_getwh (struct grub_term_output *term __attribute__ ((unused))) { return (virtual_screen.columns << 8) | virtual_screen.rows; } static grub_uint16_t -grub_virtual_screen_getxy (void) +grub_virtual_screen_getxy (struct grub_term_output *term __attribute__ ((unused))) { return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y); } static void -grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y) +grub_gfxterm_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) { if (x >= virtual_screen.columns) x = virtual_screen.columns - 1; @@ -1005,7 +1009,7 @@ grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y) } static void -grub_virtual_screen_cls (void) +grub_virtual_screen_cls (struct grub_term_output *term __attribute__ ((unused))) { grub_uint32_t i; @@ -1016,12 +1020,12 @@ grub_virtual_screen_cls (void) } static void -grub_gfxterm_cls (void) +grub_gfxterm_cls (struct grub_term_output *term) { grub_video_color_t color; /* Clear virtual screen. */ - grub_virtual_screen_cls (); + grub_virtual_screen_cls (term); /* Clear text layer. */ grub_video_set_active_render_target (text_layer); @@ -1033,11 +1037,12 @@ grub_gfxterm_cls (void) /* Mark virtual screen to be redrawn. */ dirty_region_add_virtualscreen (); - grub_gfxterm_refresh (); + grub_gfxterm_refresh (term); } static void -grub_virtual_screen_setcolorstate (grub_term_color_state state) +grub_virtual_screen_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + grub_term_color_state state) { switch (state) { @@ -1062,7 +1067,8 @@ grub_virtual_screen_setcolorstate (grub_term_color_state state) } static void -grub_virtual_screen_setcolor (grub_uint8_t normal_color, +grub_virtual_screen_setcolor (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t normal_color, grub_uint8_t highlight_color) { virtual_screen.normal_color_setting = normal_color; @@ -1070,7 +1076,8 @@ grub_virtual_screen_setcolor (grub_uint8_t normal_color, } static void -grub_virtual_screen_getcolor (grub_uint8_t *normal_color, +grub_virtual_screen_getcolor (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t *normal_color, grub_uint8_t *highlight_color) { *normal_color = virtual_screen.normal_color_setting; @@ -1078,7 +1085,8 @@ grub_virtual_screen_getcolor (grub_uint8_t *normal_color, } static void -grub_gfxterm_setcursor (int on) +grub_gfxterm_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) { if (virtual_screen.cursor_state != on) { @@ -1092,7 +1100,7 @@ grub_gfxterm_setcursor (int on) } static void -grub_gfxterm_refresh (void) +grub_gfxterm_refresh (struct grub_term_output *term __attribute__ ((unused))) { real_scroll (); diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 146e16643..c157f482c 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -30,7 +30,7 @@ static const struct grub_machine_bios_data_area *bios_data_area = #define KEYBOARD_ALT (1 << 3) static int -grub_console_getkeystatus (void) +grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused))) { grub_uint8_t status = bios_data_area->keyboard_flag_lower; int mods = 0; diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c index 036ac592a..a9dd5e214 100644 --- a/term/i386/pc/vga.c +++ b/term/i386/pc/vga.c @@ -152,7 +152,7 @@ set_start_address (unsigned int start) } static grub_err_t -grub_vga_mod_init (void) +grub_vga_mod_init (struct grub_term_output *term __attribute__ ((unused))) { text_mode = grub_vga_set_mode (0x10); cursor_state = 1; @@ -169,7 +169,7 @@ grub_vga_mod_init (void) } static grub_err_t -grub_vga_mod_fini (void) +grub_vga_mod_fini (struct grub_term_output *term __attribute__ ((unused))) { set_map_mask (saved_map_mask); grub_vga_set_mode (text_mode); @@ -287,7 +287,8 @@ scroll_up (void) } static void -grub_vga_putchar (const struct grub_unicode_glyph *c) +grub_vga_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { #if DEBUG_VGA static int show = 1; @@ -393,7 +394,8 @@ grub_vga_putchar (const struct grub_unicode_glyph *c) } static grub_ssize_t -grub_vga_getcharwidth (const struct grub_unicode_glyph *c) +grub_vga_getcharwidth (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { #if 0 struct grub_font_glyph glyph; @@ -408,19 +410,20 @@ grub_vga_getcharwidth (const struct grub_unicode_glyph *c) } static grub_uint16_t -grub_vga_getwh (void) +grub_vga_getwh (struct grub_term_output *term __attribute__ ((unused))) { return (TEXT_WIDTH << 8) | TEXT_HEIGHT; } static grub_uint16_t -grub_vga_getxy (void) +grub_vga_getxy (struct grub_term_output *term __attribute__ ((unused))) { return ((xpos << 8) | ypos); } static void -grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y) +grub_vga_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) { if (x >= TEXT_WIDTH || y >= TEXT_HEIGHT) { @@ -440,7 +443,7 @@ grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y) } static void -grub_vga_cls (void) +grub_vga_cls (struct grub_term_output *term __attribute__ ((unused))) { unsigned i; @@ -460,7 +463,8 @@ grub_vga_cls (void) } static void -grub_vga_setcolorstate (grub_term_color_state state) +grub_vga_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + grub_term_color_state state) { switch (state) { @@ -479,7 +483,8 @@ grub_vga_setcolorstate (grub_term_color_state state) } static void -grub_vga_setcursor (int on) +grub_vga_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) { if (cursor_state != on) { diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index 3f352afb4..9242adf0f 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -84,7 +84,8 @@ inc_x (void) } static void -grub_vga_text_putchar (const struct grub_unicode_glyph *c) +grub_vga_text_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { switch (c->base) { @@ -108,13 +109,14 @@ grub_vga_text_putchar (const struct grub_unicode_glyph *c) } static grub_uint16_t -grub_vga_text_getxy (void) +grub_vga_text_getxy (struct grub_term_output *term __attribute__ ((unused))) { return (grub_curr_x << 8) | grub_curr_y; } static void -grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y) +grub_vga_text_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) { grub_curr_x = x; grub_curr_y = y; @@ -122,16 +124,17 @@ grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y) } static void -grub_vga_text_cls (void) +grub_vga_text_cls (struct grub_term_output *term) { 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); + grub_vga_text_gotoxy (term, 0, 0); } static void -grub_vga_text_setcursor (int on) +grub_vga_text_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) { grub_uint8_t old; grub_outb (CRTC_CURSOR, CRTC_ADDR_PORT); @@ -143,9 +146,9 @@ grub_vga_text_setcursor (int on) } static grub_err_t -grub_vga_text_init_fini (void) +grub_vga_text_init_fini (struct grub_term_output *term) { - grub_vga_text_cls (); + grub_vga_text_cls (term); return 0; } diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c index 894c5d911..16dc8c56b 100644 --- a/term/i386/vga_common.c +++ b/term/i386/vga_common.c @@ -26,13 +26,14 @@ static grub_uint8_t grub_console_normal_color = 0x7; static grub_uint8_t grub_console_highlight_color = 0x70; grub_uint16_t -grub_console_getwh (void) +grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) { return (80 << 8) | 25; } void -grub_console_setcolorstate (grub_term_color_state state) +grub_console_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + grub_term_color_state state) { switch (state) { case GRUB_TERM_COLOR_STANDARD: @@ -50,14 +51,16 @@ grub_console_setcolorstate (grub_term_color_state state) } void -grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) +grub_console_setcolor (struct grub_term_output *term __attribute__ ((unused)), + 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) +grub_console_getcolor (struct grub_term_output *term __attribute__ ((unused)), + 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 index b9b60901b..590fa7f53 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -77,7 +77,8 @@ grub_ofconsole_writeesc (const char *str) } static void -grub_ofconsole_putchar (const struct grub_unicode_glyph *c) +grub_ofconsole_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { char chr; @@ -109,7 +110,8 @@ grub_ofconsole_putchar (const struct grub_unicode_glyph *c) } static void -grub_ofconsole_setcolorstate (grub_term_color_state state) +grub_ofconsole_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + grub_term_color_state state) { char setcol[256]; int fg; @@ -135,7 +137,8 @@ grub_ofconsole_setcolorstate (grub_term_color_state state) } static void -grub_ofconsole_setcolor (grub_uint8_t normal_color, +grub_ofconsole_setcolor (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t normal_color, grub_uint8_t highlight_color) { /* Discard bright bit. */ @@ -144,7 +147,8 @@ grub_ofconsole_setcolor (grub_uint8_t normal_color, } static void -grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) +grub_ofconsole_getcolor (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t *normal_color, grub_uint8_t *highlight_color) { *normal_color = grub_ofconsole_normal_color; *highlight_color = grub_ofconsole_highlight_color; @@ -163,7 +167,7 @@ readkey (void) } static int -grub_ofconsole_checkkey (void) +grub_ofconsole_checkkey (struct grub_term_input *term __attribute__ ((unused))) { if (grub_buflen) return grub_keybuf[0]; @@ -177,7 +181,7 @@ grub_ofconsole_checkkey (void) } static int -grub_ofconsole_getkey (void) +grub_ofconsole_getkey (struct grub_term_input *term __attribute__ ((unused))) { int ret; while (! grub_buflen) @@ -190,7 +194,7 @@ grub_ofconsole_getkey (void) } static grub_uint16_t -grub_ofconsole_getxy (void) +grub_ofconsole_getxy (struct grub_term_output *term __attribute__ ((unused))) { return (grub_curr_x << 8) | grub_curr_y; } @@ -232,13 +236,14 @@ grub_ofconsole_dimensions (void) } static grub_uint16_t -grub_ofconsole_getwh (void) +grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused))) { return (grub_ofconsole_width << 8) | grub_ofconsole_height; } static void -grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y) +grub_ofconsole_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) { if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) { @@ -265,17 +270,18 @@ grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y) } static void -grub_ofconsole_cls (void) +grub_ofconsole_cls (struct grub_term_output *term) { /* 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_ofconsole_gotoxy (0, 0); + grub_ofconsole_gotoxy (term, 0, 0); } static void -grub_ofconsole_setcursor (int on) +grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) { /* Understood by the Open Firmware flavour in OLPC. */ if (on) @@ -285,13 +291,13 @@ grub_ofconsole_setcursor (int on) } static void -grub_ofconsole_refresh (void) +grub_ofconsole_refresh (struct grub_term_output *term __attribute__ ((unused))) { /* Do nothing, the current console state is ok. */ } static grub_err_t -grub_ofconsole_init_input (void) +grub_ofconsole_init_input (struct grub_term_input *term __attribute__ ((unused))) { grub_ssize_t actual; @@ -304,7 +310,7 @@ grub_ofconsole_init_input (void) } static grub_err_t -grub_ofconsole_init_output (void) +grub_ofconsole_init_output (struct grub_term_output *term) { grub_ssize_t actual; @@ -328,7 +334,7 @@ grub_ofconsole_init_output (void) colors[col].green, colors[col].blue); /* Set the right fg and bg colors. */ - grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL); + grub_ofconsole_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); } grub_ofconsole_dimensions (); @@ -336,19 +342,11 @@ grub_ofconsole_init_output (void) 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, }; @@ -357,7 +355,6 @@ static struct grub_term_output grub_ofconsole_term_output = { .name = "ofconsole", .init = grub_ofconsole_init_output, - .fini = grub_ofconsole_fini, .putchar = grub_ofconsole_putchar, .getxy = grub_ofconsole_getxy, .getwh = grub_ofconsole_getwh, diff --git a/term/serial.c b/term/serial.c index bdc80cb74..61bad192f 100644 --- a/term/serial.c +++ b/term/serial.c @@ -154,7 +154,7 @@ serial_get_divisor (unsigned int speed) /* The serial version of checkkey. */ static int -grub_serial_checkkey (void) +grub_serial_checkkey (struct grub_term_input *term __attribute__ ((unused))) { if (npending) return input_buf[0]; @@ -169,7 +169,7 @@ grub_serial_checkkey (void) /* The serial version of getkey. */ static int -grub_serial_getkey (void) +grub_serial_getkey (struct grub_term_input *term __attribute__ ((unused))) { int ret; while (! npending) @@ -219,8 +219,8 @@ serial_hw_init (void) #endif /* Drain the input buffer. */ - while (grub_serial_checkkey () != -1) - (void) grub_serial_getkey (); + while (grub_serial_checkkey (0) != -1) + (void) grub_serial_getkey (0); /* FIXME: should check if the serial terminal was found. */ @@ -229,7 +229,8 @@ serial_hw_init (void) /* The serial version of putchar. */ static void -grub_serial_putchar (const struct grub_unicode_glyph *c) +grub_serial_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { /* Keep track of the cursor. */ if (keep_track) @@ -274,19 +275,20 @@ grub_serial_putchar (const struct grub_unicode_glyph *c) } static grub_uint16_t -grub_serial_getwh (void) +grub_serial_getwh (struct grub_term_output *term __attribute__ ((unused))) { return (TEXT_WIDTH << 8) | TEXT_HEIGHT; } static grub_uint16_t -grub_serial_getxy (void) +grub_serial_getxy (struct grub_term_output *term __attribute__ ((unused))) { return ((xpos << 8) | ypos); } static void -grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y) +grub_serial_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) { if (x > TEXT_WIDTH || y > TEXT_HEIGHT) { @@ -304,7 +306,7 @@ grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y) } static void -grub_serial_cls (void) +grub_serial_cls (struct grub_term_output *term __attribute__ ((unused))) { keep_track = 0; grub_terminfo_cls (&grub_serial_term_output); @@ -314,7 +316,8 @@ grub_serial_cls (void) } static void -grub_serial_setcolorstate (const grub_term_color_state state) +grub_serial_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + const grub_term_color_state state) { keep_track = 0; switch (state) @@ -333,7 +336,8 @@ grub_serial_setcolorstate (const grub_term_color_state state) } static void -grub_serial_setcursor (const int on) +grub_serial_setcursor (struct grub_term_output *term __attribute__ ((unused)), + const int on) { if (on) grub_terminfo_cursor_on (&grub_serial_term_output); diff --git a/term/terminfo.c b/term/terminfo.c index ef713e151..eb14d47f1 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -122,7 +122,7 @@ putstr (const char *str, grub_term_output_t oterm) .ncomb = 0, .combining = 0 }; - oterm->putchar (&c); + oterm->putchar (oterm, &c); } } diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 5d76c5e02..51855c09b 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -120,7 +120,7 @@ grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report) static int -grub_usb_keyboard_checkkey (void) +grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused))) { grub_uint8_t data[8]; int key; @@ -189,7 +189,7 @@ typedef enum } grub_usb_keyboard_repeat_t; static int -grub_usb_keyboard_getkey (void) +grub_usb_keyboard_getkey (struct grub_term_input *term) { int key; grub_err_t err; @@ -202,7 +202,7 @@ grub_usb_keyboard_getkey (void) do { - key = grub_usb_keyboard_checkkey (); + key = grub_usb_keyboard_checkkey (term); } while (key == -1); data[2] = !0; /* Or whatever. */ @@ -254,7 +254,7 @@ grub_usb_keyboard_getkey (void) } static int -grub_usb_keyboard_getkeystatus (void) +grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unused))) { grub_uint8_t data[8]; int mods = 0; diff --git a/util/console.c b/util/console.c index b4316042e..e8ee9f7da 100644 --- a/util/console.c +++ b/util/console.c @@ -64,13 +64,15 @@ static grub_uint8_t color_map[NUM_COLORS] = static int use_color; static void -grub_ncurses_putchar (const struct grub_unicode_glyph *c) +grub_ncurses_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) { addch (c->base | grub_console_attr); } static void -grub_ncurses_setcolorstate (grub_term_color_state state) +grub_ncurses_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + grub_term_color_state state) { switch (state) { @@ -104,14 +106,16 @@ grub_ncurses_setcolorstate (grub_term_color_state state) /* XXX: This function is never called. */ static void -grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) +grub_ncurses_setcolor (struct grub_term_output *term __attribute__ ((unused)), + 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) +grub_ncurses_getcolor (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t *normal_color, grub_uint8_t *highlight_color) { *normal_color = grub_console_normal_color; *highlight_color = grub_console_highlight_color; @@ -120,7 +124,7 @@ grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color static int saved_char = ERR; static int -grub_ncurses_checkkey (void) +grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused))) { int c; @@ -142,7 +146,7 @@ grub_ncurses_checkkey (void) } static int -grub_ncurses_getkey (void) +grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused))) { int c; @@ -212,7 +216,7 @@ grub_ncurses_getkey (void) } static grub_uint16_t -grub_ncurses_getxy (void) +grub_ncurses_getxy (struct grub_term_output *term __attribute__ ((unused))) { int x; int y; @@ -223,7 +227,7 @@ grub_ncurses_getxy (void) } static grub_uint16_t -grub_ncurses_getwh (void) +grub_ncurses_getwh (struct grub_term_output *term __attribute__ ((unused))) { int x; int y; @@ -234,32 +238,34 @@ grub_ncurses_getwh (void) } static void -grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y) +grub_ncurses_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) { move (y, x); } static void -grub_ncurses_cls (void) +grub_ncurses_cls (struct grub_term_output *term __attribute__ ((unused))) { clear (); refresh (); } static void -grub_ncurses_setcursor (int on) +grub_ncurses_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) { curs_set (on ? 1 : 0); } static void -grub_ncurses_refresh (void) +grub_ncurses_refresh (struct grub_term_output *term __attribute__ ((unused))) { refresh (); } static grub_err_t -grub_ncurses_init (void) +grub_ncurses_init (struct grub_term_output *term __attribute__ ((unused))) { initscr (); raw (); @@ -291,7 +297,7 @@ grub_ncurses_init (void) } static grub_err_t -grub_ncurses_fini (void) +grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused))) { endwin (); return 0; @@ -333,5 +339,5 @@ grub_console_init (void) void grub_console_fini (void) { - grub_ncurses_fini (); + grub_ncurses_fini (&grub_ncurses_term_output); } From e9efa0fe368d21bd6bc6eed7b8427341dbe5de71 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 7 May 2010 10:08:09 +0530 Subject: [PATCH 179/503] shift command support --- conf/common.rmk | 2 +- conf/tests.rmk | 4 +++ include/grub/script_sh.h | 5 +++ script/execute.c | 33 ++++++++++++++++-- script/main.c | 3 ++ tests/grub_script_shift.in | 69 ++++++++++++++++++++++++++++++++++++++ util/grub-script-check.c | 8 +++++ 7 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 tests/grub_script_shift.in diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..01f15dc59 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -106,7 +106,7 @@ util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ util/grub-script-check.c util/misc.c util/mm.c \ script/main.c script/script.c script/function.c script/lexer.c \ - kern/handler.c kern/err.c kern/parser.c kern/list.c \ + kern/handler.c kern/err.c kern/parser.c kern/list.c kern/command.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ grub_script.yy.c grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS) diff --git a/conf/tests.rmk b/conf/tests.rmk index 9144e5528..9cda007db 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -74,6 +74,9 @@ grub_script_comments_SOURCES = tests/grub_script_comments.in check_SCRIPTS += grub_script_functions grub_script_functions_SOURCES = tests/grub_script_functions.in +check_SCRIPTS += grub_script_shift +grub_script_shift_SOURCES = tests/grub_script_shift.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -91,6 +94,7 @@ SCRIPTED_TESTS += grub_script_final_semicolon SCRIPTED_TESTS += grub_script_dollar SCRIPTED_TESTS += grub_script_comments SCRIPTED_TESTS += grub_script_functions +SCRIPTED_TESTS += grub_script_shift # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 730aa3005..8610348f6 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -23,6 +23,7 @@ #include #include #include +#include struct grub_script_mem; @@ -80,6 +81,7 @@ struct grub_script_scope char **args; unsigned int argc; + unsigned int shift; }; /* A single command line. */ @@ -308,6 +310,9 @@ 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); +/* SHIFT command for GRUB script. */ +grub_err_t grub_script_cmd_shift (grub_command_t cmd, int argc, char *argv[]); + /* This variable points to the parsed command. This is used to communicate with the bison code. */ extern struct grub_script_cmd *grub_script_parsed; diff --git a/script/execute.c b/script/execute.c index 571b6785b..d3f8e9b25 100644 --- a/script/execute.c +++ b/script/execute.c @@ -32,6 +32,31 @@ static struct grub_script_scope *scope = 0; +grub_err_t +grub_script_cmd_shift (grub_command_t cmd __attribute__((unused)), + int argc, char *argv[]) +{ + char *p = 0; + unsigned long n = 0; + + if (! scope) + return GRUB_ERR_NONE; + + if (argc == 0) + n = 1; + else if (argc > 1) + return GRUB_ERR_BAD_ARGUMENT; + else + { + n = grub_strtoul (argv[0], &p, 10); + if (*p != '\0') + return GRUB_ERR_BAD_ARGUMENT; + } + + scope->shift = (unsigned int)(n > scope->argc ? 0 : n); + return GRUB_ERR_NONE; +} + static char * grub_script_env_get (const char *name) { @@ -49,7 +74,10 @@ grub_script_env_get (const char *name) if (num == 0) return 0; /* XXX no file name, for now. */ - return (num > scope->argc ? 0 : scope->args[num - 1]); + if (num > scope->argc - scope->shift) + return 0; + else + return scope->args[num - 1 + scope->shift]; } else { @@ -60,7 +88,7 @@ grub_script_env_get (const char *name) else if (grub_strcmp (name, "#") == 0) { static char buf[32]; /* Rewritten everytime. */ - grub_snprintf (buf, sizeof (buf), "%u", scope->argc); + grub_snprintf (buf, sizeof (buf), "%u", scope->argc - scope->shift); return buf; } else @@ -244,6 +272,7 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args) grub_err_t ret = 0; struct grub_script_scope new_scope; + new_scope.shift = 0; new_scope.argc = argc; new_scope.args = args; grub_list_push (GRUB_AS_LIST_P (&scope), GRUB_AS_LIST (&new_scope)); diff --git a/script/main.c b/script/main.c index b5159dc7d..ef810611c 100644 --- a/script/main.c +++ b/script/main.c @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -49,6 +50,8 @@ static struct grub_parser grub_sh_parser = GRUB_MOD_INIT(sh) { grub_parser_register ("grub", &grub_sh_parser); + grub_register_command ("shift", grub_script_cmd_shift, + N_("[n]"), N_("Shift positional parameters.")); } GRUB_MOD_FINI(sh) diff --git a/tests/grub_script_shift.in b/tests/grub_script_shift.in new file mode 100644 index 000000000..542e72974 --- /dev/null +++ b/tests/grub_script_shift.in @@ -0,0 +1,69 @@ +#! @builddir@/grub-shell-tester + +# Run GRUB script in a Qemu instance +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +function f1 { + echo f1 $# $1 $2 $3 + shift + echo f1 $# $1 $2 $3 +} + +function f2 { + echo f2 $# $1 $2 $3 + shift 1 + echo f2 $# $1 $2 $3 +} + +function f3 { + echo f3 $# $1 $2 $3 + shift 3 + echo f3 $# $1 $2 $3 +} + +function f4 { + echo f4 $# $1 $2 $3 + shift 100 + echo f4 $# $1 $2 $3 +} + +f1 +f1 a +f1 a b +f1 a b c +f1 a b c d +f1 a b c d e + +f2 +f2 a +f2 a b +f2 a b c +f2 a b c d +f2 a b c d e + +f3 +f3 a +f3 a b +f3 a b c +f3 a b c d +f3 a b c d e + +f4 +f4 a +f4 a b +f4 a b c +f4 a b c d +f4 a b c d e diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 3b7ab295d..1d9ebd57f 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -57,6 +57,14 @@ grub_refresh (void) fflush (stdout); } +grub_err_t +grub_script_cmd_shift (grub_command_t cmd __attribute__((unused)), + int argc __attribute__((unused)), + char *argv[] __attribute__((unused))) +{ + return 0; +} + char * grub_script_execute_argument_to_string (struct grub_script_arg *arg __attribute__ ((unused))) { From bf8733749b11bacaee099c72e9a9178b29055af0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 7 May 2010 15:44:43 +0200 Subject: [PATCH 180/503] merge common serial and ofconsole code into terminfo --- include/grub/{i386 => }/ieee1275/console.h | 3 +- include/grub/powerpc/ieee1275/console.h | 28 -- include/grub/sparc64/ieee1275/console.h | 28 -- include/grub/terminfo.h | 68 +++- kern/ieee1275/init.c | 5 +- term/ieee1275/ofconsole.c | 241 +++--------- term/serial.c | 189 ++-------- term/terminfo.c | 412 +++++++++++++++++---- term/tparm.c | 3 + 9 files changed, 483 insertions(+), 494 deletions(-) rename include/grub/{i386 => }/ieee1275/console.h (92%) delete mode 100644 include/grub/powerpc/ieee1275/console.h delete mode 100644 include/grub/sparc64/ieee1275/console.h diff --git a/include/grub/i386/ieee1275/console.h b/include/grub/ieee1275/console.h similarity index 92% rename from include/grub/i386/ieee1275/console.h rename to include/grub/ieee1275/console.h index 854724ac1..e054f54f5 100644 --- a/include/grub/i386/ieee1275/console.h +++ b/include/grub/ieee1275/console.h @@ -22,7 +22,8 @@ #include /* Initialize the console system. */ -void grub_console_init (void); +void grub_console_init_early (void); +void grub_console_init_lately (void); /* Finish the console system. */ void grub_console_fini (void); diff --git a/include/grub/powerpc/ieee1275/console.h b/include/grub/powerpc/ieee1275/console.h deleted file mode 100644 index ed2b7202a..000000000 --- a/include/grub/powerpc/ieee1275/console.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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/console.h b/include/grub/sparc64/ieee1275/console.h deleted file mode 100644 index ed2b7202a..000000000 --- a/include/grub/sparc64/ieee1275/console.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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/terminfo.h b/include/grub/terminfo.h index f078871d0..54872caa8 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -23,18 +23,64 @@ #include #include -char *EXPORT_FUNC(grub_terminfo_get_current) (void); -grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (const char *); - -void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_uint8_t x, grub_uint8_t y, - grub_term_output_t oterm); -void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t oterm); -void EXPORT_FUNC(grub_terminfo_reverse_video_on) (grub_term_output_t oterm); -void EXPORT_FUNC(grub_terminfo_reverse_video_off) (grub_term_output_t oterm); -void EXPORT_FUNC(grub_terminfo_cursor_on) (grub_term_output_t oterm); -void EXPORT_FUNC(grub_terminfo_cursor_off) (grub_term_output_t oterm); +char *EXPORT_FUNC(grub_terminfo_get_current) (struct grub_term_output *term); +grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (struct grub_term_output *term, + const char *); #define GRUB_TERMINFO_READKEY_MAX_LEN 4 -void EXPORT_FUNC(grub_terminfo_readkey) (int *keys, int *len, int (*readkey) (void)); +struct grub_terminfo_input_state +{ + int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN]; + int npending; + int (*readkey) (void); +}; + +struct grub_terminfo_output_state +{ + struct grub_term_output *next; + + char *name; + + char *gotoxy; + char *cls; + char *reverse_video_on; + char *reverse_video_off; + char *cursor_on; + char *cursor_off; + char *setcolor; + + grub_uint8_t normal_color; + grub_uint8_t highlight_color; + + unsigned int xpos, ypos; + + void (*put) (const int c); +}; + +void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_term_output_t term, + grub_uint8_t x, grub_uint8_t y); +void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t term); +grub_uint16_t EXPORT_FUNC (grub_terminfo_getxy) (struct grub_term_output *term); +void EXPORT_FUNC (grub_terminfo_setcursor) (struct grub_term_output *term, + const int on); +void EXPORT_FUNC (grub_terminfo_setcolorstate) (struct grub_term_output *term, + const grub_term_color_state state); + + +int EXPORT_FUNC (grub_terminfo_checkkey) (struct grub_term_input *term); +grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term); +int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term); +void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term, + const struct grub_unicode_glyph *c); +void EXPORT_FUNC (grub_terminfo_getcolor) (struct grub_term_output *term, + grub_uint8_t *normal_color, + grub_uint8_t *highlight_color); +void EXPORT_FUNC (grub_terminfo_setcolor) (struct grub_term_output *term, + grub_uint8_t normal_color, + grub_uint8_t highlight_color); + +grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term, + const char *type); +grub_err_t EXPORT_FUNC (grub_terminfo_output_unregister) (struct grub_term_output *term); #endif /* ! GRUB_TERMINFO_HEADER */ diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index b48df37bc..1a408fb73 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -225,11 +225,12 @@ grub_machine_init (void) grub_ieee1275_init (); - grub_console_init (); + grub_console_init_early (); #ifdef __i386__ grub_get_extended_memory (); #endif grub_claim_heap (); + grub_console_init_lately (); grub_ofdisk_init (); /* Process commandline. */ diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 590fa7f53..d143a6313 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include static grub_ieee1275_ihandle_t stdout_ihandle; @@ -32,12 +32,6 @@ 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[GRUB_TERMINFO_READKEY_MAX_LEN]; -static int grub_buflen; - struct color { int red; @@ -58,102 +52,14 @@ static struct color colors[] = {0xFE, 0xFE, 0xFE} // 7 = white }; -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) +put (const int c) { - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) - return; + char chr = c; - while (*str) - { - char chr = *(str++); - grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); - } - -} - -static void -grub_ofconsole_putchar (struct grub_term_output *term __attribute__ ((unused)), - const struct grub_unicode_glyph *c) -{ - char chr; - - chr = c->base; - - if (chr == '\n') - { - grub_curr_y++; - grub_curr_x = 0; - } - else if (chr == '\r') - { - grub_curr_x = 0; - } - else - { - grub_curr_x++; - if (grub_curr_x >= grub_ofconsole_width) - { - chr = '\n'; - grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); - chr = '\r'; - grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); - grub_curr_y++; - grub_curr_x = 1; - } - } grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); } -static void -grub_ofconsole_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), - grub_term_color_state state) -{ - char setcol[256]; - 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_snprintf (setcol, sizeof (setcol), "\e[3%dm\e[4%dm", fg, bg); - grub_ofconsole_writeesc (setcol); -} - -static void -grub_ofconsole_setcolor (struct grub_term_output *term __attribute__ ((unused)), - grub_uint8_t normal_color, - grub_uint8_t highlight_color) -{ - /* Discard bright bit. */ - grub_ofconsole_normal_color = normal_color & 0x77; - grub_ofconsole_highlight_color = highlight_color & 0x77; -} - -static void -grub_ofconsole_getcolor (struct grub_term_output *term __attribute__ ((unused)), - grub_uint8_t *normal_color, grub_uint8_t *highlight_color) -{ - *normal_color = grub_ofconsole_normal_color; - *highlight_color = grub_ofconsole_highlight_color; -} - static int readkey (void) { @@ -166,39 +72,6 @@ readkey (void) return -1; } -static int -grub_ofconsole_checkkey (struct grub_term_input *term __attribute__ ((unused))) -{ - if (grub_buflen) - return grub_keybuf[0]; - - grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey); - - if (grub_buflen) - return grub_keybuf[0]; - - return -1; -} - -static int -grub_ofconsole_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - int ret; - while (! grub_buflen) - grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey); - - ret = grub_keybuf[0]; - grub_buflen--; - grub_memmove (grub_keybuf, grub_keybuf + 1, grub_buflen); - return ret; -} - -static grub_uint16_t -grub_ofconsole_getxy (struct grub_term_output *term __attribute__ ((unused))) -{ - return (grub_curr_x << 8) | grub_curr_y; -} - static void grub_ofconsole_dimensions (void) { @@ -241,44 +114,6 @@ grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused))) return (grub_ofconsole_width << 8) | grub_ofconsole_height; } -static void -grub_ofconsole_gotoxy (struct grub_term_output *term __attribute__ ((unused)), - grub_uint8_t x, grub_uint8_t y) -{ - if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) - { - char s[256]; - grub_curr_x = x; - grub_curr_y = y; - - grub_snprintf (s, sizeof (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 (struct grub_term_output *term) -{ - /* 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_ofconsole_gotoxy (term, 0, 0); -} - static void grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)), int on) @@ -290,14 +125,8 @@ grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)) grub_ieee1275_interpret ("cursor-off", 0); } -static void -grub_ofconsole_refresh (struct grub_term_output *term __attribute__ ((unused))) -{ - /* Do nothing, the current console state is ok. */ -} - static grub_err_t -grub_ofconsole_init_input (struct grub_term_input *term __attribute__ ((unused))) +grub_ofconsole_init_input (struct grub_term_input *term) { grub_ssize_t actual; @@ -306,7 +135,7 @@ grub_ofconsole_init_input (struct grub_term_input *term __attribute__ ((unused)) || actual != sizeof stdin_ihandle) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin"); - return 0; + return grub_terminfo_input_init (term); } static grub_err_t @@ -333,8 +162,8 @@ grub_ofconsole_init_output (struct grub_term_output *term) 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 (term, GRUB_TERM_COLOR_NORMAL); + /* Set the right fg and bg colors. */ + grub_terminfo_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); } grub_ofconsole_dimensions (); @@ -343,41 +172,73 @@ grub_ofconsole_init_output (struct grub_term_output *term) } + +struct grub_terminfo_input_state grub_ofconsole_terminfo_input = + { + .readkey = readkey + }; + +struct grub_terminfo_output_state grub_ofconsole_terminfo_output = + { + .put = put + }; + static struct grub_term_input grub_ofconsole_term_input = { .name = "ofconsole", .init = grub_ofconsole_init_input, - .checkkey = grub_ofconsole_checkkey, - .getkey = grub_ofconsole_getkey, + .checkkey = grub_terminfo_checkkey, + .getkey = grub_terminfo_getkey, + .data = &grub_ofconsole_terminfo_input }; static struct grub_term_output grub_ofconsole_term_output = { .name = "ofconsole", .init = grub_ofconsole_init_output, - .putchar = grub_ofconsole_putchar, - .getxy = grub_ofconsole_getxy, + .putchar = grub_terminfo_putchar, + .getxy = grub_terminfo_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, + .gotoxy = grub_terminfo_gotoxy, + .cls = grub_terminfo_cls, + .setcolorstate = grub_terminfo_setcolorstate, + .setcolor = grub_terminfo_setcolor, + .getcolor = grub_terminfo_getcolor, .setcursor = grub_ofconsole_setcursor, - .refresh = grub_ofconsole_refresh, - .flags = GRUB_TERM_CODE_TYPE_ASCII + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_ofconsole_terminfo_output }; +void grub_terminfo_fini (void); +void grub_terminfo_init (void); + void -grub_console_init (void) +grub_console_init_early (void) { grub_term_register_input ("ofconsole", &grub_ofconsole_term_input); grub_term_register_output ("ofconsole", &grub_ofconsole_term_output); } +void +grub_console_init_lately (void) +{ + const char *type; + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) + type = "dumb"; + else + type = "ieee1275"; + + grub_terminfo_init (); + grub_terminfo_output_register (&grub_ofconsole_term_output, type); +} + void grub_console_fini (void) { grub_term_unregister_input (&grub_ofconsole_term_input); grub_term_unregister_output (&grub_ofconsole_term_output); + grub_terminfo_output_unregister (&grub_ofconsole_term_output); + + grub_terminfo_fini (); } diff --git a/term/serial.c b/term/serial.c index 61bad192f..82bf6abb7 100644 --- a/term/serial.c +++ b/term/serial.c @@ -27,19 +27,8 @@ #include #include -#define TEXT_WIDTH 80 -#define TEXT_HEIGHT 24 - -static unsigned int xpos, ypos; -static unsigned int keep_track = 1; static unsigned int registered = 0; -/* An input buffer. */ -static int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN]; -static int npending = 0; - -static struct grub_term_output grub_serial_term_output; - /* Argument options. */ static const struct grub_arg_option options[] = { @@ -152,35 +141,6 @@ serial_get_divisor (unsigned int speed) return 0; } -/* The serial version of checkkey. */ -static int -grub_serial_checkkey (struct grub_term_input *term __attribute__ ((unused))) -{ - if (npending) - return input_buf[0]; - - grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch); - - if (npending) - return input_buf[0]; - - return -1; -} - -/* The serial version of getkey. */ -static int -grub_serial_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - int ret; - while (! npending) - grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch); - - ret = input_buf[0]; - npending--; - grub_memmove (input_buf, input_buf + 1, npending); - return ret; -} - /* 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 @@ -219,150 +179,56 @@ serial_hw_init (void) #endif /* Drain the input buffer. */ - while (grub_serial_checkkey (0) != -1) - (void) grub_serial_getkey (0); + while (serial_hw_fetch () != -1); /* FIXME: should check if the serial terminal was found. */ return GRUB_ERR_NONE; } -/* The serial version of putchar. */ -static void -grub_serial_putchar (struct grub_term_output *term __attribute__ ((unused)), - const struct grub_unicode_glyph *c) -{ - /* Keep track of the cursor. */ - if (keep_track) - { - switch (c->base) - { - case '\a': - break; - - case '\b': - case 127: - if (xpos > 0) - xpos--; - break; - - case '\n': - if (ypos < TEXT_HEIGHT - 1) - ypos++; - break; - - case '\r': - xpos = 0; - break; - - default: - if ((c->base & 0xC0) == 0x80) - break; - if (xpos + c->estimated_width >= TEXT_WIDTH + 1) - { - xpos = 0; - if (ypos < TEXT_HEIGHT - 1) - ypos++; - serial_hw_put ('\r'); - serial_hw_put ('\n'); - } - xpos += c->estimated_width; - break; - } - } - - serial_hw_put (c->base); -} - static grub_uint16_t grub_serial_getwh (struct grub_term_output *term __attribute__ ((unused))) { + const grub_uint8_t TEXT_WIDTH = 80; + const grub_uint8_t TEXT_HEIGHT = 24; return (TEXT_WIDTH << 8) | TEXT_HEIGHT; } -static grub_uint16_t -grub_serial_getxy (struct grub_term_output *term __attribute__ ((unused))) -{ - return ((xpos << 8) | ypos); -} +struct grub_terminfo_input_state grub_serial_terminfo_input = + { + .readkey = serial_hw_fetch + }; -static void -grub_serial_gotoxy (struct grub_term_output *term __attribute__ ((unused)), - 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, &grub_serial_term_output); - keep_track = 1; - - xpos = x; - ypos = y; - } -} - -static void -grub_serial_cls (struct grub_term_output *term __attribute__ ((unused))) -{ - keep_track = 0; - grub_terminfo_cls (&grub_serial_term_output); - keep_track = 1; - - xpos = ypos = 0; -} - -static void -grub_serial_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), - 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 (&grub_serial_term_output); - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - grub_terminfo_reverse_video_on (&grub_serial_term_output); - break; - default: - break; - } - keep_track = 1; -} - -static void -grub_serial_setcursor (struct grub_term_output *term __attribute__ ((unused)), - const int on) -{ - if (on) - grub_terminfo_cursor_on (&grub_serial_term_output); - else - grub_terminfo_cursor_off (&grub_serial_term_output); -} +struct grub_terminfo_output_state grub_serial_terminfo_output = + { + .put = serial_hw_put, + .normal_color = 0x7, + .highlight_color = 0x70 + }; static struct grub_term_input grub_serial_term_input = { .name = "serial", - .checkkey = grub_serial_checkkey, - .getkey = grub_serial_getkey, + .init = grub_terminfo_input_init, + .checkkey = grub_terminfo_checkkey, + .getkey = grub_terminfo_getkey, + .data = &grub_serial_terminfo_input }; static struct grub_term_output grub_serial_term_output = { .name = "serial", - .putchar = grub_serial_putchar, + .putchar = grub_terminfo_putchar, .getwh = grub_serial_getwh, - .getxy = grub_serial_getxy, - .gotoxy = grub_serial_gotoxy, - .cls = grub_serial_cls, - .setcolorstate = grub_serial_setcolorstate, - .setcursor = grub_serial_setcursor, + .getxy = grub_terminfo_getxy, + .gotoxy = grub_terminfo_gotoxy, + .cls = grub_terminfo_cls, + .setcolorstate = grub_terminfo_setcolorstate, + .setcolor = grub_terminfo_setcolor, + .getcolor = grub_terminfo_getcolor, + .setcursor = grub_terminfo_setcursor, .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_serial_terminfo_output }; @@ -466,6 +332,7 @@ grub_cmd_serial (grub_extcmd_t cmd, { grub_term_register_input ("serial", &grub_serial_term_input); grub_term_register_output ("serial", &grub_serial_term_output); + grub_terminfo_output_register (&grub_serial_term_output, "vt100"); registered = 1; } } @@ -482,6 +349,7 @@ grub_cmd_serial (grub_extcmd_t cmd, /* If unable to restore settings, unregister terminal. */ grub_term_unregister_input (&grub_serial_term_input); grub_term_unregister_output (&grub_serial_term_output); + grub_terminfo_output_unregister (&grub_serial_term_output); registered = 0; } } @@ -518,5 +386,6 @@ GRUB_MOD_FINI(serial) { grub_term_unregister_input (&grub_serial_term_input); grub_term_unregister_output (&grub_serial_term_output); + grub_terminfo_output_unregister (&grub_serial_term_output); } } diff --git a/term/terminfo.c b/term/terminfo.c index eb14d47f1..f0e234106 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -34,25 +34,15 @@ #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; +static struct grub_term_output *terminfo_outputs; /* Get current terminfo name. */ char * -grub_terminfo_get_current (void) +grub_terminfo_get_current (struct grub_term_output *term) { - return term.name; + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + return data->name; } /* Free *PTR and set *PTR to NULL, to prevent double-free. */ @@ -63,10 +53,29 @@ grub_terminfo_free (char **ptr) *ptr = 0; } +static void +grub_terminfo_all_free (struct grub_term_output *term) +{ + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + /* Free previously allocated memory. */ + grub_terminfo_free (&data->name); + grub_terminfo_free (&data->gotoxy); + grub_terminfo_free (&data->cls); + grub_terminfo_free (&data->reverse_video_on); + grub_terminfo_free (&data->reverse_video_off); + grub_terminfo_free (&data->cursor_on); + grub_terminfo_free (&data->cursor_off); +} + /* Set current terminfo type. */ grub_err_t -grub_terminfo_set_current (const char *str) +grub_terminfo_set_current (struct grub_term_output *term, + const char *str) { + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; /* TODO * Lookup user specified terminfo type. If found, set term variables * as appropriate. Otherwise return an error. @@ -84,93 +93,290 @@ grub_terminfo_set_current (const char *str) * 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); + grub_terminfo_all_free (term); 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"); + data->name = grub_strdup ("vt100"); + data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); + data->cls = grub_strdup ("\e[H\e[J"); + data->reverse_video_on = grub_strdup ("\e[7m"); + data->reverse_video_off = grub_strdup ("\e[m"); + data->cursor_on = grub_strdup ("\e[?25h"); + data->cursor_off = grub_strdup ("\e[?25l"); + data->setcolor = NULL; + return grub_errno; + } + + if (grub_strcmp ("vt100-color", str) == 0) + { + data->name = grub_strdup ("vt100-color"); + data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); + data->cls = grub_strdup ("\e[H\e[J"); + data->reverse_video_on = grub_strdup ("\e[7m"); + data->reverse_video_off = grub_strdup ("\e[m"); + data->cursor_on = grub_strdup ("\e[?25h"); + data->cursor_off = grub_strdup ("\e[?25l"); + data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm"); + return grub_errno; + } + + if (grub_strcmp ("ieee1275", str) == 0) + { + data->name = grub_strdup ("ieee1275"); + data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); + /* 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. */ + data->cls = grub_strdup (" \e[2J"); + data->reverse_video_on = grub_strdup ("\e[7m"); + data->reverse_video_off = grub_strdup ("\e[m"); + data->cursor_on = grub_strdup ("\e[?25h"); + data->cursor_off = grub_strdup ("\e[?25l"); + data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm"); + return grub_errno; + } + + if (grub_strcmp ("dumb", str) == 0) + { + data->name = grub_strdup ("dumb"); + data->gotoxy = NULL; + data->cls = NULL; + data->reverse_video_on = NULL; + data->reverse_video_off = NULL; + data->cursor_on = NULL; + data->cursor_off = NULL; + data->setcolor = NULL; 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, grub_term_output_t oterm) +grub_err_t +grub_terminfo_output_register (struct grub_term_output *term, + const char *type) { - while (*str) - { - struct grub_unicode_glyph c = - { - .base = *str++, - .variant = 0, - .attributes = 0, - .ncomb = 0, - .combining = 0 - }; - oterm->putchar (oterm, &c); - } + grub_err_t err; + struct grub_terminfo_output_state *data; + + err = grub_terminfo_set_current (term, type); + + if (err) + return err; + + data = (struct grub_terminfo_output_state *) term->data; + data->next = terminfo_outputs; + terminfo_outputs = term; + + data->normal_color = 0x07; + data->highlight_color = 0x70; + + return GRUB_ERR_NONE; } -/* Move the cursor to the given position starting with "0". */ -void -grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm) +grub_err_t +grub_terminfo_output_unregister (struct grub_term_output *term) { - putstr (grub_terminfo_tparm (term.gotoxy, y, x), oterm); + struct grub_term_output **ptr; + + for (ptr = &terminfo_outputs; *ptr; + ptr = &((struct grub_terminfo_output_state *) (*ptr)->data)->next) + if (*ptr == term) + { + grub_terminfo_all_free (term); + *ptr = ((struct grub_terminfo_output_state *) (*ptr)->data)->next; + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "terminal not found"); +} + +/* Wrapper for grub_putchar to write strings. */ +static void +putstr (struct grub_term_output *term, const char *str) +{ + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + while (*str) + data->put (*str++); +} + +grub_uint16_t +grub_terminfo_getxy (struct grub_term_output *term) +{ + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + return ((data->xpos << 8) | data->ypos); +} + +void +grub_terminfo_gotoxy (struct grub_term_output *term, + grub_uint8_t x, grub_uint8_t y) +{ + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + if (x > grub_term_width (term) || y > grub_term_height (term)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y); + return; + } + + if (data->gotoxy) + putstr (term, grub_terminfo_tparm (data->gotoxy, y, x)); + else + { + if ((y == data->ypos) && (x == data->xpos - 1)) + data->put ('\b'); + } + + data->xpos = x; + data->ypos = y; } /* Clear the screen. */ void -grub_terminfo_cls (grub_term_output_t oterm) +grub_terminfo_cls (struct grub_term_output *term) { - putstr (grub_terminfo_tparm (term.cls), oterm); + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + putstr (term, grub_terminfo_tparm (data->cls)); + + data->xpos = data->ypos = 0; } -/* Set reverse video mode on. */ void -grub_terminfo_reverse_video_on (grub_term_output_t oterm) +grub_terminfo_setcolor (struct grub_term_output *term, + grub_uint8_t normal_color, + grub_uint8_t highlight_color) { - putstr (grub_terminfo_tparm (term.reverse_video_on), oterm); + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + /* Discard bright bit. */ + data->normal_color = normal_color & 0x77; + data->highlight_color = highlight_color & 0x77; } -/* Set reverse video mode off. */ void -grub_terminfo_reverse_video_off (grub_term_output_t oterm) +grub_terminfo_getcolor (struct grub_term_output *term, + grub_uint8_t *normal_color, + grub_uint8_t *highlight_color) { - putstr (grub_terminfo_tparm (term.reverse_video_off), oterm); + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + *normal_color = data->normal_color; + *highlight_color = data->highlight_color; } -/* Show cursor. */ void -grub_terminfo_cursor_on (grub_term_output_t oterm) +grub_terminfo_setcolorstate (struct grub_term_output *term, + const grub_term_color_state state) { - putstr (grub_terminfo_tparm (term.cursor_on), oterm); + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + if (data->setcolor) + { + int fg; + int bg; + + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + case GRUB_TERM_COLOR_NORMAL: + fg = data->normal_color & 0x0f; + bg = data->normal_color >> 4; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + fg = data->highlight_color & 0x0f; + bg = data->highlight_color >> 4; + break; + default: + return; + } + + putstr (term, grub_terminfo_tparm (data->setcolor, fg, bg)); + return; + } + + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + case GRUB_TERM_COLOR_NORMAL: + putstr (term, grub_terminfo_tparm (data->reverse_video_off)); + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + putstr (term, grub_terminfo_tparm (data->reverse_video_on)); + break; + default: + break; + } } -/* Hide cursor. */ void -grub_terminfo_cursor_off (grub_term_output_t oterm) +grub_terminfo_setcursor (struct grub_term_output *term, const int on) { - putstr (grub_terminfo_tparm (term.cursor_off), oterm); + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + if (on) + putstr (term, grub_terminfo_tparm (data->cursor_on)); + else + putstr (term, grub_terminfo_tparm (data->cursor_off)); +} + +/* The terminfo version of putchar. */ +void +grub_terminfo_putchar (struct grub_term_output *term, + const struct grub_unicode_glyph *c) +{ + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + /* Keep track of the cursor. */ + switch (c->base) + { + case '\a': + break; + + case '\b': + case 127: + if (data->xpos > 0) + data->xpos--; + break; + + case '\n': + if (data->ypos < grub_term_height (term) - 1) + data->ypos++; + break; + + case '\r': + data->xpos = 0; + break; + + default: + if (data->xpos + c->estimated_width >= grub_term_width (term) + 1) + { + data->xpos = 0; + if (data->ypos < grub_term_height (term) - 1) + data->ypos++; + data->put ('\r'); + data->put ('\n'); + } + data->xpos += c->estimated_width; + break; + } + + data->put (c->base); } #define ANSI_C0 0x9b -void +static void grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void)) { int c; @@ -276,21 +482,80 @@ grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void)) #undef CONTINUE_READ } +/* The terminfo version of checkkey. */ +int +grub_terminfo_checkkey (struct grub_term_input *termi) +{ + struct grub_terminfo_input_state *data + = (struct grub_terminfo_input_state *) (termi->data); + if (data->npending) + return data->input_buf[0]; + + grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey); + + if (data->npending) + return data->input_buf[0]; + + return -1; +} + +/* The terminfo version of getkey. */ +int +grub_terminfo_getkey (struct grub_term_input *termi) +{ + struct grub_terminfo_input_state *data + = (struct grub_terminfo_input_state *) (termi->data); + int ret; + while (! data->npending) + grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey); + + ret = data->input_buf[0]; + data->npending--; + grub_memmove (data->input_buf, data->input_buf + 1, data->npending); + return ret; +} + +grub_err_t +grub_terminfo_input_init (struct grub_term_input *termi) +{ + struct grub_terminfo_input_state *data + = (struct grub_terminfo_input_state *) (termi->data); + data->npending = 0; + + return GRUB_ERR_NONE; +} + /* GRUB Command. */ static grub_err_t grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { + struct grub_term_output *cur; + if (argc == 0) - { - grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current()); - return GRUB_ERR_NONE; - } - else if (argc != 1) + { + grub_printf ("Current terminfo types: \n"); + for (cur = terminfo_outputs; cur; + cur = ((struct grub_terminfo_output_state *) cur->data)->next) + grub_printf ("%s: %s\n", cur->name, + grub_terminfo_get_current(cur)); + + return GRUB_ERR_NONE; + } + + if (argc == 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few parameters"); + if (argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters"); - else - return grub_terminfo_set_current (args[0]); + + for (cur = terminfo_outputs; cur; + cur = ((struct grub_terminfo_output_state *) cur->data)->next) + if (grub_strcmp (args[0], cur->name) == 0) + return grub_terminfo_set_current (cur, args[1]); + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no terminal %s found or it's not handled by terminfo", + args[0]); } static grub_command_t cmd; @@ -298,8 +563,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(terminfo) { cmd = grub_register_command ("terminfo", grub_cmd_terminfo, - N_("[TERM]"), N_("Set terminfo type.")); - grub_terminfo_set_current ("vt100"); + N_("[TERM TYPE]"), N_("Set terminfo type of TERM to TYPE.")); } GRUB_MOD_FINI(terminfo) diff --git a/term/tparm.c b/term/tparm.c index adf0b3a7c..076a192a5 100644 --- a/term/tparm.c +++ b/term/tparm.c @@ -751,6 +751,9 @@ grub_terminfo_tparm (const char *string, ...) va_list ap; char *result; + if (!string) + return ""; + va_start (ap, string); result = tparam_internal (string, ap); va_end (ap); From 710d05aa8cadae86bd41bfd8b799ec4e784220ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 7 May 2010 18:07:05 +0200 Subject: [PATCH 181/503] Support serial colors --- term/ieee1275/ofconsole.c | 12 +++++++----- term/terminfo.c | 19 +++++++++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index d143a6313..151425a91 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -39,16 +39,18 @@ struct color int blue; }; +/* Use serial colors as they are default on most firmwares and some firmwares + ignore set-color!. Additionally output may be redirected to serial. */ static struct color colors[] = { // {R, G, B} - {0x00, 0x00, 0x00}, - {0x00, 0x00, 0xA8}, // 1 = blue + {0x00, 0x00, 0x00}, // 0 = black + {0xA8, 0x00, 0x00}, // 1 = red {0x00, 0xA8, 0x00}, // 2 = green - {0x00, 0xA8, 0xA8}, // 3 = cyan - {0xA8, 0x00, 0x00}, // 4 = red + {0xFE, 0xFE, 0x54}, // 3 = yellow + {0x00, 0x00, 0xA8}, // 4 = blue {0xA8, 0x00, 0xA8}, // 5 = magenta - {0xFE, 0xFE, 0x54}, // 6 = yellow + {0x00, 0xA8, 0xA8}, // 6 = cyan {0xFE, 0xFE, 0xFE} // 7 = white }; diff --git a/term/terminfo.c b/term/terminfo.c index f0e234106..4a07ba04f 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -255,9 +255,8 @@ grub_terminfo_setcolor (struct grub_term_output *term, struct grub_terminfo_output_state *data = (struct grub_terminfo_output_state *) term->data; - /* Discard bright bit. */ - data->normal_color = normal_color & 0x77; - data->highlight_color = highlight_color & 0x77; + data->normal_color = normal_color; + data->highlight_color = highlight_color; } void @@ -283,6 +282,17 @@ grub_terminfo_setcolorstate (struct grub_term_output *term, { int fg; int bg; + /* Map from VGA to terminal colors. */ + const int colormap[8] + = { 0, /* Black. */ + 4, /* Blue. */ + 2, /* Green. */ + 6, /* Cyan. */ + 1, /* Red. */ + 5, /* Magenta. */ + 3, /* Yellow. */ + 7, /* White. */ + }; switch (state) { @@ -299,7 +309,8 @@ grub_terminfo_setcolorstate (struct grub_term_output *term, return; } - putstr (term, grub_terminfo_tparm (data->setcolor, fg, bg)); + putstr (term, grub_terminfo_tparm (data->setcolor, colormap[fg & 7], + colormap[bg & 7])); return; } From d8e9099811f354073d8d997f4e333ba5c3e6c0e8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 May 2010 00:17:23 +0200 Subject: [PATCH 182/503] Move serial encoding handling to terminfo.c --- include/grub/term.h | 13 +++--- term/serial.c | 16 +------- term/terminfo.c | 99 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index c43eb6ff7..59a90d500 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -70,18 +70,19 @@ grub_term_color_state; /* Set when the terminal cannot do fancy things. */ #define GRUB_TERM_DUMB (1 << 2) /* Which encoding does terminal expect stream to be. */ -#define GRUB_TERM_CODE_TYPE_MASK ((1 << 5) | (1 << 4) | (1 << 3)) +#define GRUB_TERM_CODE_TYPE_SHIFT 3 +#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT) /* Only ASCII characters accepted. */ -#define GRUB_TERM_CODE_TYPE_ASCII 0 +#define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT) /* Expects VGA characters (ASCII + pseudographics). */ -#define GRUB_TERM_CODE_TYPE_VGA (1 << 3) +#define GRUB_TERM_CODE_TYPE_VGA (1 << GRUB_TERM_CODE_TYPE_SHIFT) /* UTF-8 stream in logical order. Usually used for terminals which just forward the stream to another computer. */ -#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (1 << 4) +#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT) /* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */ -#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL ((1 << 4) | (1 << 3)) +#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT) /* Glyph description in visual order. */ -#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (1 << 5) +#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << GRUB_TERM_CODE_TYPE_SHIFT) /* Bitmasks for modifier keys returned by grub_getkeystatus. */ diff --git a/term/serial.c b/term/serial.c index 82bf6abb7..46656455f 100644 --- a/term/serial.c +++ b/term/serial.c @@ -38,9 +38,6 @@ static const struct grub_arg_option options[] = {"word", 'w', 0, N_("Set the serial port word length."), 0, ARG_TYPE_INT}, {"parity", 'r', 0, N_("Set the serial port parity."), 0, ARG_TYPE_STRING}, {"stop", 't', 0, N_("Set the serial port stop bits."), 0, ARG_TYPE_INT}, - {"ascii", 'a', 0, N_("Terminal is ASCII-only."), 0, ARG_TYPE_NONE}, - {"utf8", 'l', 0, N_("Terminal is logical-ordered UTF-8."), 0, ARG_TYPE_NONE}, - {"visual-utf8", 'v', 0, N_("Terminal is visually-ordered UTF-8."), 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; @@ -201,9 +198,7 @@ struct grub_terminfo_input_state grub_serial_terminfo_input = struct grub_terminfo_output_state grub_serial_terminfo_output = { - .put = serial_hw_put, - .normal_color = 0x7, - .highlight_color = 0x70 + .put = serial_hw_put }; static struct grub_term_input grub_serial_term_input = @@ -313,15 +308,6 @@ grub_cmd_serial (grub_extcmd_t cmd, } } - grub_serial_term_output.flags &= ~GRUB_TERM_CODE_TYPE_MASK; - - if (state[7].set) - grub_serial_term_output.flags |= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; - else if (state[8].set) - grub_serial_term_output.flags |= GRUB_TERM_CODE_TYPE_UTF8_VISUAL; - else - grub_serial_term_output.flags |= GRUB_TERM_CODE_TYPE_ASCII; - /* Initialize with new settings. */ hwiniterr = serial_hw_init (); diff --git a/term/terminfo.c b/term/terminfo.c index 4a07ba04f..34d82fdbb 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -538,35 +538,100 @@ grub_terminfo_input_init (struct grub_term_input *termi) /* GRUB Command. */ +static grub_err_t +print_terminfo (void) +{ + const char *encoding_names[(GRUB_TERM_CODE_TYPE_MASK + >> GRUB_TERM_CODE_TYPE_SHIFT) + 1] + = { + /* VGA and glyph descriptor types are just for completeness, + they are not used on terminfo terminals. + */ + [GRUB_TERM_CODE_TYPE_ASCII >> GRUB_TERM_CODE_TYPE_SHIFT] = _("ASCII"), + [GRUB_TERM_CODE_TYPE_VGA >> GRUB_TERM_CODE_TYPE_SHIFT] = "VGA", + [GRUB_TERM_CODE_TYPE_UTF8_LOGICAL >> GRUB_TERM_CODE_TYPE_SHIFT] + = _("UTF-8"), + [GRUB_TERM_CODE_TYPE_UTF8_VISUAL >> GRUB_TERM_CODE_TYPE_SHIFT] + = _("UTF-8 visual"), + [GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS >> GRUB_TERM_CODE_TYPE_SHIFT] + = "Glyph descriptors", + _("Unknown"), _("Unknown"), _("Unknown") + }; + struct grub_term_output *cur; + + grub_printf ("Current terminfo types: \n"); + for (cur = terminfo_outputs; cur; + cur = ((struct grub_terminfo_output_state *) cur->data)->next) + grub_printf ("%s: %s\t%s\n", cur->name, + grub_terminfo_get_current(cur), + encoding_names[(cur->flags & GRUB_TERM_CODE_TYPE_MASK) + >> GRUB_TERM_CODE_TYPE_SHIFT]); + + return GRUB_ERR_NONE; +} + static grub_err_t grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { struct grub_term_output *cur; + int encoding = GRUB_TERM_CODE_TYPE_ASCII; + int i; + char *name = NULL, *type = NULL; if (argc == 0) - { - grub_printf ("Current terminfo types: \n"); - for (cur = terminfo_outputs; cur; - cur = ((struct grub_terminfo_output_state *) cur->data)->next) - grub_printf ("%s: %s\n", cur->name, - grub_terminfo_get_current(cur)); + return print_terminfo (); - return GRUB_ERR_NONE; + for (i = 0; i < argc; i++) + { + if (grub_strcmp (args[i], "-a") == 0 + || grub_strcmp (args[i], "--ascii") == 0) + { + encoding = GRUB_TERM_CODE_TYPE_ASCII; + continue; + } + if (grub_strcmp (args[i], "-u") == 0 + || grub_strcmp (args[i], "--utf8") == 0) + { + encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; + continue; + } + if (grub_strcmp (args[i], "-v") == 0 + || grub_strcmp (args[i], "--visual-utf8") == 0) + { + encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL; + continue; + } + if (!name) + { + name = args[i]; + continue; + } + if (!type) + { + type = args[i]; + continue; + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters"); } - if (argc == 1) + if (name == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few parameters"); - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters"); for (cur = terminfo_outputs; cur; cur = ((struct grub_terminfo_output_state *) cur->data)->next) - if (grub_strcmp (args[0], cur->name) == 0) - return grub_terminfo_set_current (cur, args[1]); + if (grub_strcmp (name, cur->name) == 0) + { + cur->flags = (cur->flags & ~GRUB_TERM_CODE_TYPE_MASK) | encoding; + if (!type) + return GRUB_ERR_NONE; + + return grub_terminfo_set_current (cur, type); + } return grub_error (GRUB_ERR_BAD_ARGUMENT, "no terminal %s found or it's not handled by terminfo", - args[0]); + name); } static grub_command_t cmd; @@ -574,7 +639,13 @@ static grub_command_t cmd; GRUB_MOD_INIT(terminfo) { cmd = grub_register_command ("terminfo", grub_cmd_terminfo, - N_("[TERM TYPE]"), N_("Set terminfo type of TERM to TYPE.")); + N_("[[-a|-u|-v] TERM [TYPE]]"), + N_("Set terminfo type of TERM to TYPE.\n" + "-a, --ascii Terminal is ASCII-only [default].\n" + "-u, --utf8 Terminal is logical-ordered UTF-8.\n" + "-v, --visual-utf8 Terminal is visually-ordered UTF-8.") + + ); } GRUB_MOD_FINI(terminfo) From 3c151d94af138fe813a42ee934f0206863d004e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 May 2010 01:06:22 +0200 Subject: [PATCH 183/503] simplify setcolor/getcolor --- include/grub/i386/vga_common.h | 6 ------ include/grub/term.h | 35 +++++++++++++-------------------- include/grub/terminfo.h | 9 --------- term/efi/console.c | 36 ++++++++-------------------------- term/gfxterm.c | 36 ++++++---------------------------- term/i386/pc/console.c | 6 +++--- term/i386/pc/vga.c | 2 ++ term/i386/pc/vga_text.c | 6 +++--- term/i386/vga_common.c | 27 ++++--------------------- term/ieee1275/ofconsole.c | 6 +++--- term/serial.c | 6 +++--- term/terminfo.c | 35 ++++----------------------------- util/console.c | 29 ++++----------------------- 13 files changed, 54 insertions(+), 185 deletions(-) diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h index 8ba09dfea..872790307 100644 --- a/include/grub/i386/vga_common.h +++ b/include/grub/i386/vga_common.h @@ -28,11 +28,5 @@ extern grub_uint8_t grub_console_cur_color; grub_uint16_t grub_console_getwh (struct grub_term_output *term); void grub_console_setcolorstate (struct grub_term_output *term, grub_term_color_state state); -void grub_console_setcolor (struct grub_term_output *term, - grub_uint8_t normal_color, - grub_uint8_t highlight_color); -void grub_console_getcolor (struct grub_term_output *term, - grub_uint8_t *normal_color, - grub_uint8_t *highlight_color); #endif /* ! GRUB_VGA_COMMON_CPU_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h index 59a90d500..5a098e293 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -195,16 +195,6 @@ struct grub_term_output void (*setcolorstate) (struct grub_term_output *term, grub_term_color_state state); - /* Set the normal color and the highlight color. The format of each - color is VGA's. */ - void (*setcolor) (struct grub_term_output *term, - 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) (struct grub_term_output *term, - grub_uint8_t *normal_color, grub_uint8_t *highlight_color); - /* Turn on/off the cursor. */ void (*setcursor) (struct grub_term_output *term, int on); @@ -214,10 +204,18 @@ struct grub_term_output /* The feature flags defined above. */ grub_uint32_t flags; + /* Current color state. */ + grub_uint8_t normal_color; + grub_uint8_t highlight_color; + void *data; }; typedef struct grub_term_output *grub_term_output_t; +#define GRUB_TERM_DEFAULT_NORMAL_COLOR 0x07 +#define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70 +#define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07 + extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled); extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled); extern struct grub_term_output *EXPORT_VAR(grub_term_outputs); @@ -361,14 +359,14 @@ grub_term_setcolorstate (struct grub_term_output *term, term->setcolorstate (term, state); } - /* Set the normal color and the highlight color. The format of each - color is VGA's. */ +/* Set the normal color and the highlight color. The format of each + color is VGA's. */ static inline void grub_term_setcolor (struct grub_term_output *term, grub_uint8_t normal_color, grub_uint8_t highlight_color) { - if (term->setcolor) - term->setcolor (term, normal_color, highlight_color); + term->normal_color = normal_color; + term->highlight_color = highlight_color; } /* Turn on/off the cursor. */ @@ -429,13 +427,8 @@ static inline void grub_term_getcolor (struct grub_term_output *term, grub_uint8_t *normal_color, grub_uint8_t *highlight_color) { - if (term->getcolor) - term->getcolor (term, normal_color, highlight_color); - else - { - *normal_color = 0x07; - *highlight_color = 0x07; - } + *normal_color = term->normal_color; + *highlight_color = term->highlight_color; } struct grub_term_autoload diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 54872caa8..d6907d7f0 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -49,9 +49,6 @@ struct grub_terminfo_output_state char *cursor_off; char *setcolor; - grub_uint8_t normal_color; - grub_uint8_t highlight_color; - unsigned int xpos, ypos; void (*put) (const int c); @@ -72,12 +69,6 @@ grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term) int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term); void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term, const struct grub_unicode_glyph *c); -void EXPORT_FUNC (grub_terminfo_getcolor) (struct grub_term_output *term, - grub_uint8_t *normal_color, - grub_uint8_t *highlight_color); -void EXPORT_FUNC (grub_terminfo_setcolor) (struct grub_term_output *term, - grub_uint8_t normal_color, - grub_uint8_t highlight_color); grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term, const char *type); diff --git a/term/efi/console.c b/term/efi/console.c index e5dab8a96..d54c1c4be 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -24,15 +24,9 @@ #include #include -static grub_uint8_t +static const 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; @@ -292,7 +286,7 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused))) } static void -grub_console_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), +grub_console_setcolorstate (struct grub_term_output *term, grub_term_color_state state) { grub_efi_simple_text_output_interface_t *o; @@ -304,32 +298,16 @@ grub_console_setcolorstate (struct grub_term_output *term __attribute__ ((unused 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); + efi_call_2 (o->set_attributes, o, term->normal_color); break; case GRUB_TERM_COLOR_HIGHLIGHT: - efi_call_2 (o->set_attributes, o, grub_console_highlight_color); + efi_call_2 (o->set_attributes, o, term->highlight_color); break; default: break; } } -static void -grub_console_setcolor (struct grub_term_output *term __attribute__ ((unused)), - 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 (struct grub_term_output *term __attribute__ ((unused)), - 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 (struct grub_term_output *term __attribute__ ((unused)), int on) @@ -356,9 +334,11 @@ static struct grub_term_output grub_console_term_output = .gotoxy = grub_console_gotoxy, .cls = grub_console_cls, .setcolorstate = grub_console_setcolorstate, - .setcolor = grub_console_setcolor, - .getcolor = grub_console_getcolor, .setcursor = grub_console_setcursor, + .normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY, + GRUB_EFI_BACKGROUND_BLACK), + .highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK, + GRUB_EFI_BACKGROUND_LIGHTGRAY), .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS }; diff --git a/term/gfxterm.c b/term/gfxterm.c index d9fb2e04c..c38e306cb 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -35,8 +35,6 @@ #define DEFAULT_BORDER_WIDTH 10 #define DEFAULT_STANDARD_COLOR 0x07 -#define DEFAULT_NORMAL_COLOR 0x07 -#define DEFAULT_HIGHLIGHT_COLOR 0x70 struct grub_dirty_region { @@ -92,8 +90,6 @@ struct grub_virtual_screen /* 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. */ @@ -260,10 +256,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, 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; + virtual_screen.term_color = GRUB_TERM_DEFAULT_NORMAL_COLOR; set_term_color (virtual_screen.term_color); @@ -1041,7 +1035,7 @@ grub_gfxterm_cls (struct grub_term_output *term) } static void -grub_virtual_screen_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), +grub_virtual_screen_setcolorstate (struct grub_term_output *term, grub_term_color_state state) { switch (state) @@ -1051,11 +1045,11 @@ grub_virtual_screen_setcolorstate (struct grub_term_output *term __attribute__ ( break; case GRUB_TERM_COLOR_NORMAL: - virtual_screen.term_color = virtual_screen.normal_color_setting; + virtual_screen.term_color = term->normal_color; break; case GRUB_TERM_COLOR_HIGHLIGHT: - virtual_screen.term_color = virtual_screen.highlight_color_setting; + virtual_screen.term_color = term->highlight_color; break; default: @@ -1066,24 +1060,6 @@ grub_virtual_screen_setcolorstate (struct grub_term_output *term __attribute__ ( set_term_color (virtual_screen.term_color); } -static void -grub_virtual_screen_setcolor (struct grub_term_output *term __attribute__ ((unused)), - 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 (struct grub_term_output *term __attribute__ ((unused)), - 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 (struct grub_term_output *term __attribute__ ((unused)), int on) @@ -1211,11 +1187,11 @@ static struct grub_term_output grub_video_term = .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 = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, .next = 0 }; diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index c157f482c..2a7e34ad4 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -62,10 +62,10 @@ static struct grub_term_output grub_console_term_output = .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 = GRUB_TERM_CODE_TYPE_VGA + .flags = GRUB_TERM_CODE_TYPE_VGA, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, }; void diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c index a9dd5e214..ace0504d4 100644 --- a/term/i386/pc/vga.c +++ b/term/i386/pc/vga.c @@ -511,6 +511,8 @@ static struct grub_term_output grub_vga_term = .setcolorstate = grub_vga_setcolorstate, .setcursor = grub_vga_setcursor, .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, }; GRUB_MOD_INIT(vga) diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index 9242adf0f..60bde5b05 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -163,10 +163,10 @@ static struct grub_term_output grub_vga_text_term = .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, - .flags = GRUB_TERM_CODE_TYPE_VGA + .flags = GRUB_TERM_CODE_TYPE_VGA, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, }; GRUB_MOD_INIT(vga_text) diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c index 16dc8c56b..02fb5c02d 100644 --- a/term/i386/vga_common.c +++ b/term/i386/vga_common.c @@ -21,9 +21,6 @@ #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; grub_uint16_t grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) @@ -32,36 +29,20 @@ grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) } void -grub_console_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), +grub_console_setcolorstate (struct grub_term_output *term, grub_term_color_state state) { switch (state) { case GRUB_TERM_COLOR_STANDARD: - grub_console_cur_color = grub_console_standard_color; + grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR; break; case GRUB_TERM_COLOR_NORMAL: - grub_console_cur_color = grub_console_normal_color; + grub_console_cur_color = term->normal_color; break; case GRUB_TERM_COLOR_HIGHLIGHT: - grub_console_cur_color = grub_console_highlight_color; + grub_console_cur_color = term->highlight_color; break; default: break; } } - -void -grub_console_setcolor (struct grub_term_output *term __attribute__ ((unused)), - 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 (struct grub_term_output *term __attribute__ ((unused)), - 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 index 151425a91..604906ceb 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -204,11 +204,11 @@ static struct grub_term_output grub_ofconsole_term_output = .gotoxy = grub_terminfo_gotoxy, .cls = grub_terminfo_cls, .setcolorstate = grub_terminfo_setcolorstate, - .setcolor = grub_terminfo_setcolor, - .getcolor = grub_terminfo_getcolor, .setcursor = grub_ofconsole_setcursor, .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_ofconsole_terminfo_output + .data = &grub_ofconsole_terminfo_output, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, }; void grub_terminfo_fini (void); diff --git a/term/serial.c b/term/serial.c index 46656455f..d97ead60a 100644 --- a/term/serial.c +++ b/term/serial.c @@ -219,11 +219,11 @@ static struct grub_term_output grub_serial_term_output = .gotoxy = grub_terminfo_gotoxy, .cls = grub_terminfo_cls, .setcolorstate = grub_terminfo_setcolorstate, - .setcolor = grub_terminfo_setcolor, - .getcolor = grub_terminfo_getcolor, .setcursor = grub_terminfo_setcursor, .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_serial_terminfo_output + .data = &grub_serial_terminfo_output, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, }; diff --git a/term/terminfo.c b/term/terminfo.c index 34d82fdbb..dcf17106a 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -168,9 +168,6 @@ grub_terminfo_output_register (struct grub_term_output *term, data = (struct grub_terminfo_output_state *) term->data; data->next = terminfo_outputs; terminfo_outputs = term; - - data->normal_color = 0x07; - data->highlight_color = 0x70; return GRUB_ERR_NONE; } @@ -247,30 +244,6 @@ grub_terminfo_cls (struct grub_term_output *term) data->xpos = data->ypos = 0; } -void -grub_terminfo_setcolor (struct grub_term_output *term, - grub_uint8_t normal_color, - grub_uint8_t highlight_color) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - data->normal_color = normal_color; - data->highlight_color = highlight_color; -} - -void -grub_terminfo_getcolor (struct grub_term_output *term, - grub_uint8_t *normal_color, - grub_uint8_t *highlight_color) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - *normal_color = data->normal_color; - *highlight_color = data->highlight_color; -} - void grub_terminfo_setcolorstate (struct grub_term_output *term, const grub_term_color_state state) @@ -298,12 +271,12 @@ grub_terminfo_setcolorstate (struct grub_term_output *term, { case GRUB_TERM_COLOR_STANDARD: case GRUB_TERM_COLOR_NORMAL: - fg = data->normal_color & 0x0f; - bg = data->normal_color >> 4; + fg = term->normal_color & 0x0f; + bg = term->normal_color >> 4; break; case GRUB_TERM_COLOR_HIGHLIGHT: - fg = data->highlight_color & 0x0f; - bg = data->highlight_color >> 4; + fg = term->highlight_color & 0x0f; + bg = term->highlight_color >> 4; break; default: return; diff --git a/util/console.c b/util/console.c index e8ee9f7da..8e5b59776 100644 --- a/util/console.c +++ b/util/console.c @@ -43,9 +43,7 @@ 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; +static const grub_uint8_t grub_console_standard_color = 0x7; #define NUM_COLORS 8 @@ -71,7 +69,7 @@ grub_ncurses_putchar (struct grub_term_output *term __attribute__ ((unused)), } static void -grub_ncurses_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), +grub_ncurses_setcolorstate (struct grub_term_output *term, grub_term_color_state state) { switch (state) @@ -81,11 +79,11 @@ grub_ncurses_setcolorstate (struct grub_term_output *term __attribute__ ((unused grub_console_attr = A_NORMAL; break; case GRUB_TERM_COLOR_NORMAL: - grub_console_cur_color = grub_console_normal_color; + grub_console_cur_color = term->normal_color; grub_console_attr = A_NORMAL; break; case GRUB_TERM_COLOR_HIGHLIGHT: - grub_console_cur_color = grub_console_highlight_color; + grub_console_cur_color = term->highlight_color; grub_console_attr = A_STANDOUT; break; default: @@ -104,23 +102,6 @@ grub_ncurses_setcolorstate (struct grub_term_output *term __attribute__ ((unused } } -/* XXX: This function is never called. */ -static void -grub_ncurses_setcolor (struct grub_term_output *term __attribute__ ((unused)), - 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 (struct grub_term_output *term __attribute__ ((unused)), - 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 @@ -322,8 +303,6 @@ static struct grub_term_output grub_ncurses_term_output = .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 = GRUB_TERM_CODE_TYPE_ASCII From 2dd54ae21d14e92744782145bc81891a3c376fea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 May 2010 01:08:58 +0200 Subject: [PATCH 184/503] macroify keys in ncusest terminal code --- util/console.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/util/console.c b/util/console.c index 8e5b59776..4704f1492 100644 --- a/util/console.c +++ b/util/console.c @@ -146,19 +146,19 @@ grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused))) switch (c) { case KEY_LEFT: - c = 2; + c = GRUB_TERM_LEFT; break; case KEY_RIGHT: - c = 6; + c = GRUB_TERM_RIGHT; break; case KEY_UP: - c = 16; + c = GRUB_TERM_UP; break; case KEY_DOWN: - c = 14; + c = GRUB_TERM_DOWN; break; case KEY_IC: @@ -166,30 +166,30 @@ grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused))) break; case KEY_DC: - c = 4; + c = GRUB_TERM_DC; break; case KEY_BACKSPACE: /* XXX: For some reason ncurses on xterm does not return KEY_BACKSPACE. */ case 127: - c = 8; + c = GRUB_TERM_BACKSPACE; break; case KEY_HOME: - c = 1; + c = GRUB_TERM_HOME; break; case KEY_END: - c = 5; + c = GRUB_TERM_END; break; case KEY_NPAGE: - c = 3; + c = GRUB_TERM_NPAGE; break; case KEY_PPAGE: - c = 7; + c = GRUB_TERM_PPAGE; break; } From d42b0387bfb546b5a4fd600c3f09293d7b622ec1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 May 2010 01:25:18 +0200 Subject: [PATCH 185/503] fix sparc64 compilation --- kern/sparc64/ieee1275/init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c index a995217bc..72ee1f136 100644 --- a/kern/sparc64/ieee1275/init.c +++ b/kern/sparc64/ieee1275/init.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -155,8 +155,9 @@ void grub_machine_init (void) { grub_ieee1275_init (); - grub_console_init (); + grub_console_init_early (); grub_heap_init (); + grub_console_init_lately (); grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); grub_ofdisk_init (); From b764bff263def3c0e60b232213ed362ee52a5fa8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 9 May 2010 12:56:32 +0200 Subject: [PATCH 186/503] Move arrow number into unicode characters array --- include/grub/term.h | 14 -------------- include/grub/unicode.h | 10 ++++++++++ normal/menu_entry.c | 8 ++++---- normal/menu_text.c | 28 ++++++++++++++-------------- normal/term.c | 40 ++++++++++++++++++++-------------------- 5 files changed, 48 insertions(+), 52 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index 5a098e293..e460e4a58 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -90,20 +90,6 @@ grub_term_color_state; #define GRUB_TERM_STATUS_CTRL (1 << 1) #define GRUB_TERM_STATUS_ALT (1 << 2) - -/* 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. */ /* The number of lines of "GRUB version..." at the top. */ diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 39e4c52cc..9d1fe7ca0 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -184,6 +184,16 @@ enum GRUB_UNICODE_THAANA_SUKUN = 0x07b0, GRUB_UNICODE_ZWNJ = 0x200c, GRUB_UNICODE_ZWJ = 0x200d, + GRUB_UNICODE_LEFTARROW = 0x2190, + GRUB_UNICODE_UPARROW = 0x2191, + GRUB_UNICODE_RIGHTARROW = 0x2192, + GRUB_UNICODE_DOWNARROW = 0x2193, + GRUB_UNICODE_HLINE = 0x2501, + GRUB_UNICODE_VLINE = 0x2503, + GRUB_UNICODE_CORNER_UL = 0x250f, + GRUB_UNICODE_CORNER_UR = 0x2513, + GRUB_UNICODE_CORNER_LL = 0x2517, + GRUB_UNICODE_CORNER_LR = 0x251b, GRUB_UNICODE_VARIATION_SELECTOR_1 = 0xfe00, GRUB_UNICODE_VARIATION_SELECTOR_16 = 0xfe0f, GRUB_UNICODE_VARIATION_SELECTOR_17 = 0xe0100, diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 433208116..d4d359066 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -173,7 +173,7 @@ print_up (int flag, struct per_term_screen *term_screen) GRUB_TERM_FIRST_ENTRY_Y); if (flag) - grub_putcode (GRUB_TERM_DISP_UP, term_screen->term); + grub_putcode (GRUB_UNICODE_UPARROW, term_screen->term); else grub_putcode (' ', term_screen->term); } @@ -188,7 +188,7 @@ print_down (int flag, struct per_term_screen *term_screen) + grub_term_num_entries (term_screen->term)); if (flag) - grub_putcode (GRUB_TERM_DISP_DOWN, term_screen->term); + grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term); else grub_putcode (' ', term_screen->term); } @@ -1097,7 +1097,7 @@ complete (struct screen *screen, int continuous, int update) endp = p + (grub_term_width (screen->terms[i].term) - 8); if (p != ucs4) - grub_putcode (GRUB_TERM_DISP_LEFT, screen->terms[i].term); + grub_putcode (GRUB_UNICODE_LEFTARROW, screen->terms[i].term); else grub_putcode (' ', screen->terms[i].term); @@ -1105,7 +1105,7 @@ complete (struct screen *screen, int continuous, int update) 0, 0, screen->terms[i].term); if (ucs4 + ucs4len > endp) - grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term); + grub_putcode (GRUB_UNICODE_RIGHTARROW, screen->terms[i].term); grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF); } } diff --git a/normal/menu_text.c b/normal/menu_text.c index 22bcbda66..3e3e7e2fa 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -83,27 +83,27 @@ draw_border (struct grub_term_output *term) grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y); - grub_putcode (GRUB_TERM_DISP_UL, term); + grub_putcode (GRUB_UNICODE_CORNER_UL, term); for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++) - grub_putcode (GRUB_TERM_DISP_HLINE, term); - grub_putcode (GRUB_TERM_DISP_UR, term); + grub_putcode (GRUB_UNICODE_HLINE, term); + grub_putcode (GRUB_UNICODE_CORNER_UR, term); for (i = 0; i < (unsigned) grub_term_num_entries (term); i++) { grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1); - grub_putcode (GRUB_TERM_DISP_VLINE, term); + grub_putcode (GRUB_UNICODE_VLINE, term); grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term) - 1, GRUB_TERM_TOP_BORDER_Y + i + 1); - grub_putcode (GRUB_TERM_DISP_VLINE, term); + grub_putcode (GRUB_UNICODE_VLINE, term); } grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1); - grub_putcode (GRUB_TERM_DISP_LL, term); + grub_putcode (GRUB_UNICODE_CORNER_LL, term); for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++) - grub_putcode (GRUB_TERM_DISP_HLINE, term); - grub_putcode (GRUB_TERM_DISP_LR, term); + grub_putcode (GRUB_UNICODE_HLINE, term); + grub_putcode (GRUB_UNICODE_CORNER_LR, term); grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); @@ -138,8 +138,8 @@ command-line or ESC to discard edits and return to the GRUB menu."), "entry is highlighted.\n"); char *msg_translated; - msg_translated = grub_xasprintf (msg, (grub_uint32_t) GRUB_TERM_DISP_UP, - (grub_uint32_t) GRUB_TERM_DISP_DOWN); + msg_translated = grub_xasprintf (msg, GRUB_UNICODE_UPARROW, + GRUB_UNICODE_DOWNARROW); if (!msg_translated) return; grub_putcode ('\n', term); @@ -236,9 +236,9 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, if (last_printed != len) { - grub_putcode (GRUB_TERM_DISP_RIGHT, term); + grub_putcode (GRUB_UNICODE_RIGHTARROW, term); struct grub_unicode_glyph pseudo_glyph = { - .base = GRUB_TERM_DISP_RIGHT, + .base = GRUB_UNICODE_RIGHTARROW, .variant = 0, .attributes = 0, .ncomb = 0, @@ -274,7 +274,7 @@ print_entries (grub_menu_t menu, int first, int offset, GRUB_TERM_FIRST_ENTRY_Y); if (first) - grub_putcode (GRUB_TERM_DISP_UP, term); + grub_putcode (GRUB_UNICODE_UPARROW, term); else grub_putcode (' ', term); @@ -292,7 +292,7 @@ print_entries (grub_menu_t menu, int first, int offset, GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)); if (e) - grub_putcode (GRUB_TERM_DISP_DOWN, term); + grub_putcode (GRUB_UNICODE_DOWNARROW, term); else grub_putcode (' ', term); diff --git a/normal/term.c b/normal/term.c index f46930be4..4d7dbf622 100644 --- a/normal/term.c +++ b/normal/term.c @@ -128,25 +128,25 @@ map_code (grub_uint32_t in, struct grub_term_output *term) case GRUB_TERM_CODE_TYPE_VGA: switch (in) { - case GRUB_TERM_DISP_LEFT: + case GRUB_UNICODE_LEFTARROW: return 0x1b; - case GRUB_TERM_DISP_UP: + case GRUB_UNICODE_UPARROW: return 0x18; - case GRUB_TERM_DISP_RIGHT: + case GRUB_UNICODE_RIGHTARROW: return 0x1a; - case GRUB_TERM_DISP_DOWN: + case GRUB_UNICODE_DOWNARROW: return 0x19; - case GRUB_TERM_DISP_HLINE: + case GRUB_UNICODE_HLINE: return 0xc4; - case GRUB_TERM_DISP_VLINE: + case GRUB_UNICODE_VLINE: return 0xb3; - case GRUB_TERM_DISP_UL: + case GRUB_UNICODE_CORNER_UL: return 0xda; - case GRUB_TERM_DISP_UR: + case GRUB_UNICODE_CORNER_UR: return 0xbf; - case GRUB_TERM_DISP_LL: + case GRUB_UNICODE_CORNER_LL: return 0xc0; - case GRUB_TERM_DISP_LR: + case GRUB_UNICODE_CORNER_LR: return 0xd9; } return '?'; @@ -154,28 +154,28 @@ map_code (grub_uint32_t in, struct grub_term_output *term) /* Better than nothing. */ switch (in) { - case GRUB_TERM_DISP_LEFT: + case GRUB_UNICODE_LEFTARROW: return '<'; - case GRUB_TERM_DISP_UP: + case GRUB_UNICODE_UPARROW: return '^'; - case GRUB_TERM_DISP_RIGHT: + case GRUB_UNICODE_RIGHTARROW: return '>'; - case GRUB_TERM_DISP_DOWN: + case GRUB_UNICODE_DOWNARROW: return 'v'; - case GRUB_TERM_DISP_HLINE: + case GRUB_UNICODE_HLINE: return '-'; - case GRUB_TERM_DISP_VLINE: + case GRUB_UNICODE_VLINE: return '|'; - case GRUB_TERM_DISP_UL: - case GRUB_TERM_DISP_UR: - case GRUB_TERM_DISP_LL: - case GRUB_TERM_DISP_LR: + case GRUB_UNICODE_CORNER_UL: + case GRUB_UNICODE_CORNER_UR: + case GRUB_UNICODE_CORNER_LL: + case GRUB_UNICODE_CORNER_LR: return '+'; } From d7fd78dc3d95747639cbbd42c28cf77c22c26543 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 9 May 2010 13:20:35 +0200 Subject: [PATCH 187/503] macroify EFI characters mapping --- include/grub/unicode.h | 10 ++++++ term/efi/console.c | 71 +++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/include/grub/unicode.h b/include/grub/unicode.h index 9d1fe7ca0..64769258a 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -188,12 +188,22 @@ enum GRUB_UNICODE_UPARROW = 0x2191, GRUB_UNICODE_RIGHTARROW = 0x2192, GRUB_UNICODE_DOWNARROW = 0x2193, + GRUB_UNICODE_LIGHT_HLINE = 0x2500, GRUB_UNICODE_HLINE = 0x2501, + GRUB_UNICODE_LIGHT_VLINE = 0x2502, GRUB_UNICODE_VLINE = 0x2503, + GRUB_UNICODE_LIGHT_CORNER_UL = 0x250c, GRUB_UNICODE_CORNER_UL = 0x250f, + GRUB_UNICODE_LIGHT_CORNER_UR = 0x2510, GRUB_UNICODE_CORNER_UR = 0x2513, + GRUB_UNICODE_LIGHT_CORNER_LL = 0x2514, GRUB_UNICODE_CORNER_LL = 0x2517, + GRUB_UNICODE_LIGHT_CORNER_LR = 0x2518, GRUB_UNICODE_CORNER_LR = 0x251b, + GRUB_UNICODE_BLACK_UP_TRIANGLE = 0x25b2, + GRUB_UNICODE_BLACK_RIGHT_TRIANGLE = 0x25ba, + GRUB_UNICODE_BLACK_DOWN_TRIANGLE = 0x25bc, + GRUB_UNICODE_BLACK_LEFT_TRIANGLE = 0x25c4, GRUB_UNICODE_VARIATION_SELECTOR_1 = 0xfe00, GRUB_UNICODE_VARIATION_SELECTOR_16 = 0xfe0f, GRUB_UNICODE_VARIATION_SELECTOR_17 = 0xe0100, diff --git a/term/efi/console.c b/term/efi/console.c index d54c1c4be..d3240590b 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -33,46 +33,39 @@ 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) { - /* 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; - } + case GRUB_UNICODE_LEFTARROW: + c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE; + break; + case GRUB_UNICODE_UPARROW: + c = GRUB_UNICODE_BLACK_UP_TRIANGLE; + break; + case GRUB_UNICODE_RIGHTARROW: + c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE; + break; + case GRUB_UNICODE_DOWNARROW: + c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE; + break; + case GRUB_UNICODE_HLINE: + c = GRUB_UNICODE_LIGHT_HLINE; + break; + case GRUB_UNICODE_VLINE: + c = GRUB_UNICODE_LIGHT_VLINE; + break; + case GRUB_UNICODE_CORNER_UL: + c = GRUB_UNICODE_LIGHT_CORNER_UL; + break; + case GRUB_UNICODE_CORNER_UR: + c = GRUB_UNICODE_LIGHT_CORNER_UR; + break; + case GRUB_UNICODE_CORNER_LL: + c = GRUB_UNICODE_LIGHT_CORNER_LL; + break; + case GRUB_UNICODE_CORNER_LR: + c = GRUB_UNICODE_LIGHT_CORNER_LR; + break; } return c; From 232dbbe509dbee800eb65be87d9abc19849b86c3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 9 May 2010 13:26:52 +0200 Subject: [PATCH 188/503] Rename 'VGA' character set to CP-437 --- include/grub/term.h | 4 ++-- normal/term.c | 2 +- term/i386/pc/console.c | 2 +- term/i386/pc/vga_text.c | 2 +- term/terminfo.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index e460e4a58..c744c3fb6 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -74,8 +74,8 @@ grub_term_color_state; #define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT) /* Only ASCII characters accepted. */ #define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT) -/* Expects VGA characters (ASCII + pseudographics). */ -#define GRUB_TERM_CODE_TYPE_VGA (1 << GRUB_TERM_CODE_TYPE_SHIFT) +/* Expects CP-437 characters (ASCII + pseudographics). */ +#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT) /* UTF-8 stream in logical order. Usually used for terminals which just forward the stream to another computer. */ #define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT) diff --git a/normal/term.c b/normal/term.c index 4d7dbf622..2689f18b6 100644 --- a/normal/term.c +++ b/normal/term.c @@ -125,7 +125,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term) switch (term->flags & GRUB_TERM_CODE_TYPE_MASK) { - case GRUB_TERM_CODE_TYPE_VGA: + case GRUB_TERM_CODE_TYPE_CP437: switch (in) { case GRUB_UNICODE_LEFTARROW: diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 2a7e34ad4..19a8e3814 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -63,7 +63,7 @@ static struct grub_term_output grub_console_term_output = .cls = grub_console_cls, .setcolorstate = grub_console_setcolorstate, .setcursor = grub_console_setcursor, - .flags = GRUB_TERM_CODE_TYPE_VGA, + .flags = GRUB_TERM_CODE_TYPE_CP437, .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, }; diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index 60bde5b05..9fca56c29 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -164,7 +164,7 @@ static struct grub_term_output grub_vga_text_term = .cls = grub_vga_text_cls, .setcolorstate = grub_console_setcolorstate, .setcursor = grub_vga_text_setcursor, - .flags = GRUB_TERM_CODE_TYPE_VGA, + .flags = GRUB_TERM_CODE_TYPE_CP437, .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, }; diff --git a/term/terminfo.c b/term/terminfo.c index dcf17106a..ff54e5dba 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -521,7 +521,7 @@ print_terminfo (void) they are not used on terminfo terminals. */ [GRUB_TERM_CODE_TYPE_ASCII >> GRUB_TERM_CODE_TYPE_SHIFT] = _("ASCII"), - [GRUB_TERM_CODE_TYPE_VGA >> GRUB_TERM_CODE_TYPE_SHIFT] = "VGA", + [GRUB_TERM_CODE_TYPE_CP437 >> GRUB_TERM_CODE_TYPE_SHIFT] = "CP-437", [GRUB_TERM_CODE_TYPE_UTF8_LOGICAL >> GRUB_TERM_CODE_TYPE_SHIFT] = _("UTF-8"), [GRUB_TERM_CODE_TYPE_UTF8_VISUAL >> GRUB_TERM_CODE_TYPE_SHIFT] From a68c41941352bbfbb0eda2486e916aaf4d75a37c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 9 May 2010 13:37:32 +0200 Subject: [PATCH 189/503] macroify cp437 codepoints --- normal/term.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/normal/term.c b/normal/term.c index 2689f18b6..47e61c5e8 100644 --- a/normal/term.c +++ b/normal/term.c @@ -117,6 +117,20 @@ grub_set_more (int onoff) grub_normal_reset_more (); } +enum + { + GRUB_CP437_UPARROW = 0x18, + GRUB_CP437_DOWNARROW = 0x19, + GRUB_CP437_RIGHTARROW = 0x1a, + GRUB_CP437_LEFTARROW = 0x1b, + GRUB_CP437_VLINE = 0xb3, + GRUB_CP437_CORNER_UR = 0xbf, + GRUB_CP437_CORNER_LL = 0xc0, + GRUB_CP437_HLINE = 0xc4, + GRUB_CP437_CORNER_LR = 0xd9, + GRUB_CP437_CORNER_UL = 0xda, + }; + static grub_uint32_t map_code (grub_uint32_t in, struct grub_term_output *term) { @@ -129,25 +143,25 @@ map_code (grub_uint32_t in, struct grub_term_output *term) switch (in) { case GRUB_UNICODE_LEFTARROW: - return 0x1b; + return GRUB_CP437_LEFTARROW; case GRUB_UNICODE_UPARROW: - return 0x18; + return GRUB_CP437_UPARROW; case GRUB_UNICODE_RIGHTARROW: - return 0x1a; + return GRUB_CP437_RIGHTARROW; case GRUB_UNICODE_DOWNARROW: - return 0x19; + return GRUB_CP437_DOWNARROW; case GRUB_UNICODE_HLINE: - return 0xc4; + return GRUB_CP437_HLINE; case GRUB_UNICODE_VLINE: - return 0xb3; + return GRUB_CP437_VLINE; case GRUB_UNICODE_CORNER_UL: - return 0xda; + return GRUB_CP437_CORNER_UL; case GRUB_UNICODE_CORNER_UR: - return 0xbf; + return GRUB_CP437_CORNER_UR; case GRUB_UNICODE_CORNER_LL: - return 0xc0; + return GRUB_CP437_CORNER_LL; case GRUB_UNICODE_CORNER_LR: - return 0xd9; + return GRUB_CP437_CORNER_LR; } return '?'; case GRUB_TERM_CODE_TYPE_ASCII: From 01b0317f7b70fc6fe7fe73f7a36c2e4d26621255 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 11 May 2010 10:52:10 +0530 Subject: [PATCH 190/503] simplified nesting dynamic scopes --- include/grub/script_sh.h | 9 --------- script/execute.c | 13 +++++++++++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 730aa3005..e1edbec15 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -73,15 +73,6 @@ struct grub_script_arglist int argcount; }; -/* Scope for grub script constructs. */ -struct grub_script_scope -{ - struct grub_script_scope *next; - - char **args; - unsigned int argc; -}; - /* A single command line. */ struct grub_script_cmdline { diff --git a/script/execute.c b/script/execute.c index 571b6785b..573dab4cb 100644 --- a/script/execute.c +++ b/script/execute.c @@ -30,6 +30,12 @@ is sizeof (int) * 3, and one extra for a possible -ve sign. */ #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) +/* Scope for grub script functions. */ +struct grub_script_scope +{ + char **args; + unsigned int argc; +}; static struct grub_script_scope *scope = 0; static char * @@ -242,15 +248,18 @@ grub_err_t grub_script_function_call (grub_script_function_t func, int argc, char **args) { grub_err_t ret = 0; + struct grub_script_scope *old_scope; struct grub_script_scope new_scope; new_scope.argc = argc; new_scope.args = args; - grub_list_push (GRUB_AS_LIST_P (&scope), GRUB_AS_LIST (&new_scope)); + + old_scope = scope; + scope = &new_scope; ret = grub_script_execute (func->func); - grub_list_pop (GRUB_AS_LIST_P (&scope)); + scope = old_scope; return ret; } From a0167e8bdf046724f3eb227b1c4ef9c3abe6f0f5 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 12 May 2010 10:19:12 +0530 Subject: [PATCH 191/503] rewrote arglist to argv conversion and added $@, $* support --- conf/common.rmk | 2 +- include/grub/script_sh.h | 12 ++ script/argv.c | 128 ++++++++++++ script/execute.c | 362 +++++++++++++++------------------ script/yylex.l | 2 +- tests/grub_script_echo1.in | 27 +++ tests/grub_script_functions.in | 70 ++++++- tests/grub_script_vars1.in | 2 +- 8 files changed, 392 insertions(+), 213 deletions(-) create mode 100644 script/argv.c diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..54146904b 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -660,7 +660,7 @@ normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) # For sh.mod. -sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ +sh_mod_SOURCES = script/main.c script/script.c script/argv.c script/execute.c \ script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error sh_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index e1edbec15..5455fc763 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -63,6 +63,13 @@ struct grub_script_arg struct grub_script_arg *next; }; +/* An argument vector. */ +struct grub_script_argv +{ + int argc; + char **args; +}; + /* A complete argument. It consists of a list of one or more `struct grub_script_arg's. */ struct grub_script_arglist @@ -215,6 +222,11 @@ struct grub_parser_param struct grub_lexer_param *lexerstate; }; +void grub_script_argv_free (struct grub_script_argv *argv); +int grub_script_argv_next (struct grub_script_argv *argv); +int grub_script_argv_append (struct grub_script_argv *argv, const char *s); +int grub_script_argv_split_append (struct grub_script_argv *argv, char *s); + struct grub_script_arglist * grub_script_create_arglist (struct grub_parser_param *state); diff --git a/script/argv.c b/script/argv.c new file mode 100644 index 000000000..1ac81f4b8 --- /dev/null +++ b/script/argv.c @@ -0,0 +1,128 @@ +/* argv.c - methods for constructing argument vector */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 ARG_ALLOCATION_UNIT (32 * sizeof (char)) +#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*)) + +void +grub_script_argv_free (struct grub_script_argv *argv) +{ + int i; + + if (argv->args) + { + for (i = 0; i < argv->argc; i++) + grub_free (argv->args[i]); + + grub_free (argv->args); + } + + argv->argc = 0; + argv->args = 0; +} + +/* Prepare for next argc. */ +int +grub_script_argv_next (struct grub_script_argv *argv) +{ + char **p = argv->args; + + if (argv->argc == 0) + { + p = grub_malloc (ALIGN_UP (2 * sizeof (char *), ARG_ALLOCATION_UNIT)); + if (! p) + return 1; + + argv->argc = 1; + argv->args = p; + argv->args[0] = 0; + argv->args[1] = 0; + return 0; + } + + if (! argv->args[argv->argc - 1]) + return 0; + + p = grub_realloc (p, ALIGN_UP ((argv->argc + 1) * sizeof (char *), + ARG_ALLOCATION_UNIT)); + if (! p) + return 1; + + argv->argc++; + argv->args = p; + argv->args[argv->argc] = 0; + return 0; +} + +/* Append `s' to the last argument. */ +int +grub_script_argv_append (struct grub_script_argv *argv, const char *s) +{ + int a, b; + char *p = argv->args[argv->argc - 1]; + + if (! s) + return 0; + + a = p ? grub_strlen (p) : 0; + b = grub_strlen (s); + + p = grub_realloc (p, ALIGN_UP ((a + b + 1) * sizeof (char), + ARG_ALLOCATION_UNIT)); + if (! p) + return 1; + + grub_strcpy (p + a, s); + argv->args[argv->argc - 1] = p; + return 0; +} + +/* Split `s' and append words as multiple arguments. */ +int +grub_script_argv_split_append (struct grub_script_argv *argv, char *s) +{ + char ch; + char *p; + int errors = 0; + + if (! s) + return 0; + + while (! errors && *s) + { + p = s; + while (*s && ! grub_isspace (*s)) + s++; + + ch = *s; + *s = '\0'; + errors += grub_script_argv_append (argv, p); + *s = ch; + + while (*s && grub_isspace (*s)) + s++; + + if (*s) + errors += grub_script_argv_next (argv); + } + return errors; +} diff --git a/script/execute.c b/script/execute.c index 573dab4cb..905f457d3 100644 --- a/script/execute.c +++ b/script/execute.c @@ -33,55 +33,172 @@ /* Scope for grub script functions. */ struct grub_script_scope { - char **args; - unsigned int argc; + struct grub_script_argv argv; }; static struct grub_script_scope *scope = 0; -static char * -grub_script_env_get (const char *name) +static int +grub_env_special (const char *name) { - char *p = 0; - unsigned long num = 0; + if (grub_isdigit (name[0]) || + grub_strcmp (name, "#") == 0 || + grub_strcmp (name, "*") == 0 || + grub_strcmp (name, "@") == 0) + return 1; + return 0; +} - if (! scope) - return grub_env_get (name); +static char ** +grub_script_env_get (const char *name, grub_script_arg_type_t type) +{ + int errors = 0; + struct grub_script_argv result = { 0, 0 }; - if (grub_isdigit (name[0])) + errors += grub_script_argv_next (&result); + if (! grub_env_special (name)) { - num = grub_strtoul (name, &p, 10); - if (p && *p == '\0') + char *v = grub_env_get (name); + if (v && v[0]) { - if (num == 0) - return 0; /* XXX no file name, for now. */ - - return (num > scope->argc ? 0 : scope->args[num - 1]); - } - else - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "bad variabe name substitution"); - return 0; + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + errors += grub_script_argv_split_append (&result, v); + else + errors += grub_script_argv_append (&result, v); } } + else if (! scope) + errors += grub_script_argv_append (&result, 0); + else if (grub_strcmp (name, "#") == 0) { - static char buf[32]; /* Rewritten everytime. */ - grub_snprintf (buf, sizeof (buf), "%u", scope->argc); - return buf; + char buffer[ERRNO_DIGITS_MAX + 1]; + grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc); + errors += grub_script_argv_append (&result, buffer); + } + else if (grub_strcmp (name, "*") == 0) + { + int i; + + for (i = 0; ! errors && i < scope->argv.argc; i++) + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + { + if (i != 0) + errors += grub_script_argv_next (&result); + errors += grub_script_argv_split_append (&result, + scope->argv.args[i]); + } + else + { + if (i != 0) + errors += grub_script_argv_append (&result, " "); + errors += grub_script_argv_append (&result, + scope->argv.args[i]); + } + } + else if (grub_strcmp (name, "@") == 0) + { + int i; + + for (i = 0; ! errors && i < scope->argv.argc; i++) + { + if (i != 0) + errors += grub_script_argv_next (&result); + + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + errors += grub_script_argv_split_append (&result, + scope->argv.args[i]); + else + errors += grub_script_argv_append (&result, + scope->argv.args[i]); + } } else - return grub_env_get (name); + { + unsigned long num = grub_strtoul (name, 0, 10); + if (num == 0) + ; /* XXX no file name, for now. */ + + else if (num <= scope->argv.argc) + { + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + errors += grub_script_argv_split_append (&result, + scope->argv.args[num - 1]); + else + errors += grub_script_argv_append (&result, + scope->argv.args[num - 1]); + } + } + return result.args; } static grub_err_t grub_script_env_set (const char *name, const char *val) { - if (grub_isdigit (name[0]) || grub_strcmp (name, "#") == 0) + if (grub_env_special (name)) return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad variable name"); return grub_env_set (name, val); } +/* Expand arguments in ARGLIST into multiple arguments. */ +static int +grub_script_arglist_to_argv (struct grub_script_arglist *arglist, + struct grub_script_argv *argv) +{ + int i; + int error = 0; + char **values = 0; + struct grub_script_arg *arg = 0; + struct grub_script_argv result = { 0, 0 }; + + for (; error == 0 && arglist && arglist->arg; arglist = arglist->next) + { + error += grub_script_argv_next (&result); + + arg = arglist->arg; + while (arg) + { + if (error) + break; + + switch (arg->type) + { + case GRUB_SCRIPT_ARG_TYPE_VAR: + case GRUB_SCRIPT_ARG_TYPE_DQVAR: + values = grub_script_env_get (arg->str, arg->type); + for (i = 0; values && values[i]; i++) + { + if (i != 0) + error += grub_script_argv_next (&result); + error += grub_script_argv_append (&result, values[i]); + } + grub_free (values); + break; + + case GRUB_SCRIPT_ARG_TYPE_TEXT: + if (grub_strlen (arg->str)) + error += grub_script_argv_append (&result, arg->str); + break; + + case GRUB_SCRIPT_ARG_TYPE_DQSTR: + case GRUB_SCRIPT_ARG_TYPE_SQSTR: + error += grub_script_argv_append (&result, arg->str); + break; + } + arg = arg->next; + } + } + + if (error) + return 1; + + if (! result.args[result.argc - 1]) + result.argc--; + + *argv = result; + return 0; +} + static grub_err_t grub_script_execute_cmd (struct grub_script_cmd *cmd) { @@ -98,151 +215,6 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd) return ret; } -#define ARG_ALLOCATION_UNIT (32 * sizeof (char)) -#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*)) - -/* Expand arguments in ARGLIST into multiple arguments. */ -char ** -grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count) -{ - int i; - int oom; - int argc; - int empty; - char *ptr; - char **argv; - char *value; - struct grub_script_arg *arg; - - auto void push (char *str); - void push (char *str) - { - char **p; - - if (oom) - return; - - p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), ARGV_ALLOCATION_UNIT)); - if (!p) - oom = 1; - else - { - p[argc++] = str; - argv = p; - } - } - - auto char* append (const char *str, grub_size_t nchar); - char* append (const char *str, grub_size_t nchar) - { - int len; - int old; - char *p; - - if (oom || !str) - return 0; - - len = nchar ?: grub_strlen (str); - old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0; - p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, ARG_ALLOCATION_UNIT)); - - if (p) - { - grub_strncpy (p + old, str, len); - p[old + len] = '\0'; - } - else - { - oom = 1; - grub_free (argv[argc - 1]); - } - argv[argc - 1] = p; - return argv[argc - 1]; - } - - /* Move *STR to the begining of next word, but return current word. */ - auto char* move_to_next (char **str); - char* move_to_next (char **str) - { - char *end; - char *start; - - if (oom || !str || !*str) - return 0; - - start = *str; - while (*start && grub_isspace (*start)) start++; - if (*start == '\0') - return 0; - - end = start + 1; - while (*end && !grub_isspace (*end)) end++; - - *str = end; - return start; - } - - oom = 0; - argv = 0; - argc = 0; - push (0); - for (; arglist; arglist = arglist->next) - { - empty = 1; - arg = arglist->arg; - while (arg) - { - switch (arg->type) - { - case GRUB_SCRIPT_ARG_TYPE_VAR: - value = grub_script_env_get (arg->str); - while (value && *value && (ptr = move_to_next(&value))) - { - empty = 0; - append (ptr, value - ptr); - if (*value) push(0); - } - break; - - case GRUB_SCRIPT_ARG_TYPE_TEXT: - if (grub_strlen (arg->str) > 0) - { - empty = 0; - append (arg->str, 0); - } - break; - - case GRUB_SCRIPT_ARG_TYPE_DQSTR: - case GRUB_SCRIPT_ARG_TYPE_SQSTR: - empty = 0; - append (arg->str, 0); - break; - - case GRUB_SCRIPT_ARG_TYPE_DQVAR: - empty = 0; - append (grub_script_env_get (arg->str), 0); - break; - } - arg = arg->next; - } - if (!empty) - push (0); - } - - if (oom) - { - for (i = 0; i < argc; i++) - grub_free (argv[i]); - grub_free (argv); - argv = 0; - } - - if (argv) - *count = argc - 1; - - return argv; -} - /* Execute a function call. */ grub_err_t grub_script_function_call (grub_script_function_t func, int argc, char **args) @@ -251,8 +223,8 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args) struct grub_script_scope *old_scope; struct grub_script_scope new_scope; - new_scope.argc = argc; - new_scope.args = args; + new_scope.argv.argc = argc; + new_scope.argv.args = args; old_scope = scope; scope = &new_scope; @@ -268,21 +240,18 @@ grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd) { struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd; - char **args = 0; - int i = 0; grub_command_t grubcmd; grub_err_t ret = 0; - int argcount = 0; grub_script_function_t func = 0; char errnobuf[18]; char *cmdname; + struct grub_script_argv argv = { 0, 0 }; /* Lookup the command. */ - args = grub_script_execute_arglist_to_argv (cmdline->arglist, &argcount); - if (!args) + if (grub_script_arglist_to_argv (cmdline->arglist, &argv)) return grub_errno; - cmdname = args[0]; + cmdname = argv.args[0]; grubcmd = grub_command_find (cmdname); if (! grubcmd) { @@ -319,14 +288,12 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Execute the GRUB command or function. */ if (grubcmd) - ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1); + ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1); else - ret = grub_script_function_call (func, argcount - 1, args + 1); + ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1); /* Free arguments. */ - for (i = 0; i < argcount; i++) - grub_free (args[i]); - grub_free (args); + grub_script_argv_free (&argv); if (grub_errno == GRUB_ERR_TEST_FAILURE) grub_errno = GRUB_ERR_NONE; @@ -363,7 +330,7 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd) /* 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_script_env_get ("?"); + result = grub_env_get ("?"); grub_errno = GRUB_ERR_NONE; @@ -381,23 +348,20 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) { int i; int result; - char **args; - int argcount; + struct grub_script_argv argv; struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; - args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount); - if (!args) + if (grub_script_arglist_to_argv (cmdfor->words, &argv)) return grub_errno; result = 0; - for (i = 0; i < argcount; i++) + for (i = 0; i < argv.argc; i++) { - grub_script_env_set (cmdfor->name->str, args[i]); + grub_script_env_set (cmdfor->name->str, argv.args[i]); result = grub_script_execute_cmd (cmdfor->list); - grub_free (args[i]); } - grub_free (args); + grub_script_argv_free (&argv); return result; } @@ -426,26 +390,20 @@ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd) { struct grub_script_cmd_menuentry *cmd_menuentry; - char **args = 0; - int argcount = 0; - int i = 0; + struct grub_script_argv argv = {0, 0}; cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd; if (cmd_menuentry->arglist) { - args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist, &argcount); - if (!args) + if (grub_script_arglist_to_argv (cmd_menuentry->arglist, &argv)) return grub_errno; } - grub_normal_add_menu_entry (argcount, (const char **) args, + grub_normal_add_menu_entry (argv.argc, (const char **) argv.args, cmd_menuentry->sourcecode); - /* Free arguments. */ - for (i = 0; i < argcount; i++) - grub_free (args[i]); - grub_free (args); + grub_script_argv_free (&argv); return grub_errno; } diff --git a/script/yylex.l b/script/yylex.l index f563ac30d..bfc53a6ff 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -119,7 +119,7 @@ DIGITS [[:digit:]]+ NAME [[:alpha:]_][[:alnum:][:digit:]_]* ESC \\. -SPECIAL \?|\# +SPECIAL \?|\#|\*|\@ VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|${SPECIAL}|$\{{SPECIAL}\} DQSTR \"([^\\\"]|{ESC})*\" SQSTR \'[^\']*\' diff --git a/tests/grub_script_echo1.in b/tests/grub_script_echo1.in index 048907a76..554dd68ed 100644 --- a/tests/grub_script_echo1.in +++ b/tests/grub_script_echo1.in @@ -16,6 +16,33 @@ # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . +# simple arguments +echo one two three +echo "one two three" +echo 'one two three' + +# empty arguments +echo a "" b +echo a '' b + +echo a $foo b +echo a ${foo} b + +echo a "$foo" b +echo a "${foo}" b + +# multi-part arguments +echo one"two"three +echo one${two}three +echo one"two"$three + +echo one'two'three +echo one${two}three +echo one'two'$three + +echo one'two'three"four"five${six}seven$eight + + foo=bar echo $foo ${foo} echo "$foo" "${foo}" diff --git a/tests/grub_script_functions.in b/tests/grub_script_functions.in index 41af87474..234a1be13 100644 --- a/tests/grub_script_functions.in +++ b/tests/grub_script_functions.in @@ -18,7 +18,7 @@ echo parameter count function fcount { - echo "$#" + echo fcount "$#" } fcount @@ -27,7 +27,7 @@ fcount a b echo parameter count, with nesting function ffcount { - echo "$#" + echo ffcount "$#" fcount fcount a fcount a b @@ -39,9 +39,9 @@ ffcount 1 2 echo parameters function fparam { - echo 1 $1 - echo 2 $2 - echo 3 $3 + echo fparam 1 $1 + echo fparam 2 $2 + echo fparam 3 $3 } fparam @@ -50,9 +50,9 @@ fparam a b echo parameters, with nesting function ffparam { - echo 1 $1 - echo 2 $2 - echo 3 $3 + echo ffparam 1 $1 + echo ffparam 2 $2 + echo ffparam 3 $3 fparam fparam a fparam a b @@ -61,3 +61,57 @@ function ffparam { ffparam ffparam 1 ffparam 1 2 + +echo parameter expansion with specials +function fstar { + for f in $* + do + echo fstar $f + done +} + +fstar +fstar a +fstar a "1 2" +fstar a "1 2" b + +function fdqstar { + for f in "$*" + do + echo fdqstar $f + done +} + +fdqstar +fdqstar a +fdqstar a "1 2" +fdqstar a "1 2" b + +function fat { + for f in $@ + do + echo fat $f + done +} + +fat +fat a +fat a "1 2" +fat a "1 2" b +fat a "1 2" b "c d" +fat a "1 2" b "c d" e + +function fdqat { + for f in "$@" + do + echo fdqat $f + done +} + +# fdqat # this case needs special handling, lets ignore till we really need it. +fdqat a +fdqat a "1 2" +fdqat a "1 2" b +fdqat a "1 2" b "c d" +fdqat a "1 2" b "c d" e + diff --git a/tests/grub_script_vars1.in b/tests/grub_script_vars1.in index 9ff897627..77b3cf298 100644 --- a/tests/grub_script_vars1.in +++ b/tests/grub_script_vars1.in @@ -28,7 +28,7 @@ foo=foo echo "" $foo echo $bar $foo - + bar="" echo $bar $foo From d13f69de73b15e7034c2ab110f3742bafbe2bf79 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 12 May 2010 10:45:22 +0530 Subject: [PATCH 192/503] handle failure case --- script/execute.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/script/execute.c b/script/execute.c index 905f457d3..5200b04a7 100644 --- a/script/execute.c +++ b/script/execute.c @@ -128,6 +128,13 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) scope->argv.args[num - 1]); } } + + if (errors) + { + grub_script_argv_free (&result); + return 0; + } + return result.args; } From 53018ca6c361f6975eaa92aea3777144b7e04b66 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 12 May 2010 13:12:49 +0530 Subject: [PATCH 193/503] minor fix --- script/execute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/execute.c b/script/execute.c index 5200b04a7..2040be13c 100644 --- a/script/execute.c +++ b/script/execute.c @@ -285,7 +285,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_free (assign); grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); - grub_script_env_set ("?", errnobuf); + grub_env_set ("?", errnobuf); grub_print_error (); From 04888e878791894927261c4a8dc34ed44b27b37d Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 12 May 2010 13:53:50 +0530 Subject: [PATCH 194/503] few more testcases added --- tests/grub_script_functions.in | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/grub_script_functions.in b/tests/grub_script_functions.in index 234a1be13..3e69014d6 100644 --- a/tests/grub_script_functions.in +++ b/tests/grub_script_functions.in @@ -68,6 +68,11 @@ function fstar { do echo fstar $f done + + for f in aaa$*bbb + do + echo fstar $f + done } fstar @@ -80,6 +85,16 @@ function fdqstar { do echo fdqstar $f done + + for f in aaa"$*"bbb + do + echo fdqstar $f + done + + for f in "aaa$*bbb" + do + echo fdqstar $f + done } fdqstar @@ -92,6 +107,11 @@ function fat { do echo fat $f done + + for f in aaa$@bbb + do + echo fat $f + done } fat @@ -106,6 +126,16 @@ function fdqat { do echo fdqat $f done + + for f in aaa"$@"bbb + do + echo fdqat $f + done + + for f in "aaa$@bbb" + do + echo fdqat $f + done } # fdqat # this case needs special handling, lets ignore till we really need it. From b4cd82945a8f2ce728e160c316fb4d1b79c7c330 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 12 May 2010 17:43:49 +0530 Subject: [PATCH 195/503] minor fix --- script/execute.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/script/execute.c b/script/execute.c index d83f51914..d2e8753c3 100644 --- a/script/execute.c +++ b/script/execute.c @@ -47,9 +47,6 @@ grub_script_cmd_shift (grub_command_t cmd __attribute__((unused)), if (! scope) return GRUB_ERR_NONE; - if (scope->argv.argc == 0) - return GRUB_ERR_NONE; - if (argc == 0) n = 1; @@ -59,10 +56,13 @@ grub_script_cmd_shift (grub_command_t cmd __attribute__((unused)), else { n = grub_strtoul (argv[0], &p, 10); - if (*p != '\0' || n > scope->argv.argc) + if (*p != '\0') return GRUB_ERR_BAD_ARGUMENT; } + if (n > scope->argv.argc) + return GRUB_ERR_BAD_ARGUMENT; + scope->argv.argc -= n; scope->argv.args += n; return GRUB_ERR_NONE; From 7b252ac27c439528e54f9c127d912b3afad76b64 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 12 May 2010 17:46:49 +0530 Subject: [PATCH 196/503] few more testcases --- tests/grub_script_shift.in | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/grub_script_shift.in b/tests/grub_script_shift.in index c7c94ab18..785b9c396 100644 --- a/tests/grub_script_shift.in +++ b/tests/grub_script_shift.in @@ -17,8 +17,12 @@ # along with GRUB. If not, see . function f1 { + echo f1 '$@' $@ + echo f1 '$*' $* echo f1 $# $1 $2 $3 shift + echo f1 '$@' $@ + echo f1 '$*' $* echo f1 $# $1 $2 $3 } @@ -30,8 +34,12 @@ f1 a b c d f1 a b c d e function f2 { + echo f1 '$@' $@ + echo f1 '$*' $* echo f2 $# $1 $2 $3 shift 1 + echo f1 '$@' $@ + echo f1 '$*' $* echo f2 $# $1 $2 $3 } @@ -43,8 +51,12 @@ f2 a b c d f2 a b c d e function f3 { + echo f1 '$@' $@ + echo f1 '$*' $* echo f3 $# $1 $2 $3 shift 3 + echo f1 '$@' $@ + echo f1 '$*' $* echo f3 $# $1 $2 $3 } @@ -56,8 +68,12 @@ f3 a b c d f3 a b c d e function f4 { + echo f1 '$@' $@ + echo f1 '$*' $* echo f4 $# $1 $2 $3 shift 100 + echo f1 '$@' $@ + echo f1 '$*' $* echo f4 $# $1 $2 $3 } From cced9145fcb1005dfde437b5f835ecfb924477eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 13 May 2010 03:56:14 +0200 Subject: [PATCH 197/503] =?UTF-8?q?=09Fix=20gfxmenu=20crash.=20=09Reported?= =?UTF-8?q?=20by:=20Thorsten=20Gr=C3=BCtzmacher.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister timeout hook. (circprog_set_property): Register and unregister timeout hook. * gfxmenu/gui_label.c (grub_gui_label): New fields template and value. (label_destroy): Free template. and unregister hook. (label_set_state): New function. (label_set_property): Handle templates and hooks. * gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister timeout hook. (progress_bar_set_property): Register and unregister timeout hook. * gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ... * include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here * gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable. (update_timeout_visit): Removed. (update_timeouts): New function. (redraw_timeouts): Likewise. (grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts. (grub_gfxmenu_clear_timeout): Likewise. * include/grub/gui.h (grub_gfxmenu_set_state_t): New type. (grub_gfxmenu_timeout_notify): Likewise. (grub_gfxmenu_timeout_notifications): New external variable. (grub_gfxmenu_timeout_register): New function. (grub_gfxmenu_timeout_unregister): Likewise. --- ChangeLog | 29 +++++++++++ gfxmenu/gui_circular_progress.c | 28 ++++++----- gfxmenu/gui_label.c | 32 +++++++++++- gfxmenu/gui_progress_bar.c | 7 +++ gfxmenu/view.c | 87 ++++++++++----------------------- include/grub/gui.h | 45 +++++++++++++++++ 6 files changed, 155 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index a388738cb..78eebc11b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2010-05-13 Vladimir Serbinenko + + Fix gfxmenu crash. + Reported by: Thorsten Grützmacher. + + * gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister + timeout hook. + (circprog_set_property): Register and unregister timeout hook. + * gfxmenu/gui_label.c (grub_gui_label): New fields template and value. + (label_destroy): Free template. and unregister hook. + (label_set_state): New function. + (label_set_property): Handle templates and hooks. + * gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister + timeout hook. + (progress_bar_set_property): Register and unregister timeout hook. + * gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ... + * include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here + * gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable. + (update_timeout_visit): Removed. + (update_timeouts): New function. + (redraw_timeouts): Likewise. + (grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts. + (grub_gfxmenu_clear_timeout): Likewise. + * include/grub/gui.h (grub_gfxmenu_set_state_t): New type. + (grub_gfxmenu_timeout_notify): Likewise. + (grub_gfxmenu_timeout_notifications): New external variable. + (grub_gfxmenu_timeout_register): New function. + (grub_gfxmenu_timeout_unregister): Likewise. + 2010-05-09 Vladimir Serbinenko Transform (broken) vga terminal into (working) vga video driver. diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c index 9a859ee2e..098ae1c92 100644 --- a/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -54,6 +54,7 @@ static void circprog_destroy (void *vself) { circular_progress_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -211,6 +212,17 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds) *bounds = self->bounds; } +static void +circprog_set_state (void *vself, int visible, int start, + int current, int end) +{ + circular_progress_t self = vself; + self->visible = visible; + self->start = start; + self->value = current; + self->end = end; +} + static grub_err_t circprog_set_property (void *vself, const char *name, const char *value) { @@ -247,26 +259,20 @@ circprog_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0) + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + circprog_set_state); } return grub_errno; } -static void -circprog_set_state (void *vself, int visible, int start, - int current, int end) -{ - circular_progress_t self = vself; - self->visible = visible; - self->start = start; - self->value = current; - self->end = end; -} - static struct grub_gui_component_ops circprog_ops = { .destroy = circprog_destroy, diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c index a9dd575ac..15a352f84 100644 --- a/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -46,8 +46,10 @@ struct grub_gui_label char *id; int visible; char *text; + char *template; grub_font_t font; grub_gui_color_t color; + int value; enum align_mode align; }; @@ -57,7 +59,9 @@ static void label_destroy (void *vself) { grub_gui_label_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->text); + grub_free (self->template); grub_free (self); } @@ -146,6 +150,17 @@ label_get_minimal_size (void *vself, unsigned *width, unsigned *height) + grub_font_get_descent (self->font)); } +static void +label_set_state (void *vself, int visible, int start __attribute__ ((unused)), + int current, int end __attribute__ ((unused))) +{ + grub_gui_label_t self = vself; + self->value = -current; + self->visible = visible; + grub_free (self->text); + self->text = grub_xasprintf (self->template ? : "%d", self->value); +} + static grub_err_t label_set_property (void *vself, const char *name, const char *value) { @@ -153,9 +168,17 @@ label_set_property (void *vself, const char *name, const char *value) if (grub_strcmp (name, "text") == 0) { grub_free (self->text); + grub_free (self->template); if (! value) - value = ""; - self->text = grub_strdup (value); + { + self->template = NULL; + self->text = grub_strdup (""); + } + else + { + self->template = grub_strdup (value); + self->text = grub_xasprintf (value, self->value); + } } else if (grub_strcmp (name, "font") == 0) { @@ -183,11 +206,16 @@ label_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0) + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + label_set_state); } return GRUB_ERR_NONE; } diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index d786aae31..e1b31794f 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -60,6 +60,7 @@ static void progress_bar_destroy (void *vself) { grub_gui_progress_bar_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -333,11 +334,16 @@ progress_bar_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + /* if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0)*/ + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + progress_bar_set_state); } return grub_errno; } @@ -368,6 +374,7 @@ grub_gui_progress_bar_new (void) self = grub_zalloc (sizeof (*self)); if (! self) return 0; + self->progress.ops = &progress_bar_pb_ops; self->progress.component.ops = &progress_bar_ops; self->visible = 1; diff --git a/gfxmenu/view.c b/gfxmenu/view.c index bf637a96d..9a5671cdd 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -37,10 +37,6 @@ #include #include -/* The component ID identifying GUI components to be updated as the timeout - status changes. */ -#define TIMEOUT_COMPONENT_ID "__timeout__" - static void init_terminal (grub_gfxmenu_view_t view); static grub_video_rect_t term_rect; @@ -166,16 +162,28 @@ struct progress_value_data int value; }; -static void -update_timeout_visit (grub_gui_component_t component, - void *userdata) -{ - struct progress_value_data *pv; - pv = (struct progress_value_data *) userdata; +struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; - ((struct grub_gui_progress *) component)->ops - ->set_state ((struct grub_gui_progress *) component, - pv->visible, pv->start, pv->value, pv->end); +static void +update_timeouts (int visible, int start, int value, int end) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + cur->set_state (cur->self, visible, start, value, end); +} + +static void +redraw_timeouts (struct grub_gfxmenu_view *view) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + { + grub_video_rect_t bounds; + cur->self->ops->get_bounds (cur->self, &bounds); + grub_gfxmenu_view_redraw (view, &bounds); + } } void @@ -183,67 +191,26 @@ grub_gfxmenu_print_timeout (int timeout, void *data) { struct grub_gfxmenu_view *view = data; - struct progress_value_data pv; - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))); - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))) - { - grub_video_rect_t bounds; - component->ops->get_bounds (component, &bounds); - grub_gfxmenu_view_redraw (view, &bounds); - } - if (view->first_timeout == -1) view->first_timeout = timeout; - pv.visible = 1; - pv.start = -(view->first_timeout + 1); - pv.end = 0; - pv.value = -timeout; - - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + update_timeouts (1, -(view->first_timeout + 1), -timeout, 0); + redraw_timeouts (view); grub_video_swap_buffers (); if (view->double_repaint) - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + redraw_timeouts (view); } void grub_gfxmenu_clear_timeout (void *data) { - struct progress_value_data pv; struct grub_gfxmenu_view *view = data; - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))); - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))) - { - grub_video_rect_t bounds; - component->ops->get_bounds (component, &bounds); - grub_gfxmenu_view_redraw (view, &bounds); - } - - pv.visible = 0; - pv.start = 1; - pv.end = 0; - pv.value = 0; - - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + update_timeouts (0, 1, 0, 0); + redraw_timeouts (view); grub_video_swap_buffers (); if (view->double_repaint) - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + redraw_timeouts (view); } static void diff --git a/include/grub/gui.h b/include/grub/gui.h index 7bd71acd3..6e4a11cbe 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -22,10 +22,15 @@ #include #include #include +#include #ifndef GRUB_GUI_H #define GRUB_GUI_H 1 +/* The component ID identifying GUI components to be updated as the timeout + status changes. */ +#define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" + /* A representation of a color. Unlike grub_video_color_t, this representation is independent of any video mode specifics. */ typedef struct grub_gui_color @@ -79,6 +84,46 @@ struct grub_gui_progress_ops void (*set_state) (void *self, int visible, int start, int current, int end); }; +typedef void (*grub_gfxmenu_set_state_t) (void *self, int visible, int start, + int current, int end); + +struct grub_gfxmenu_timeout_notify +{ + struct grub_gfxmenu_timeout_notify *next; + grub_gfxmenu_set_state_t set_state; + grub_gui_component_t self; +}; + +extern struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; + +static inline grub_err_t +grub_gfxmenu_timeout_register (grub_gui_component_t self, + grub_gfxmenu_set_state_t set_state) +{ + struct grub_gfxmenu_timeout_notify *ne = grub_malloc (sizeof (*ne)); + if (!ne) + return grub_errno; + ne->set_state = set_state; + ne->self = self; + ne->next = grub_gfxmenu_timeout_notifications; + grub_gfxmenu_timeout_notifications = ne; + return GRUB_ERR_NONE; +} + +static inline void +grub_gfxmenu_timeout_unregister (grub_gui_component_t self) +{ + struct grub_gfxmenu_timeout_notify **p, *q; + + for (p = &grub_gfxmenu_timeout_notifications, q = *p; + q; p = &(q->next), q = q->next) + if (q->self == self) + { + *p = q->next; + break; + } +} + typedef signed grub_fixed_signed_t; #define GRUB_FIXED_1 0x10000 From 94bf3dd564d4bd4aaebfb69159efb1499fc5a351 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 May 2010 01:32:07 +0200 Subject: [PATCH 198/503] somewhat working video_cirrus implementation --- conf/i386.rmk | 5 + include/grub/video.h | 3 +- video/cirrus.c | 538 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 545 insertions(+), 1 deletion(-) create mode 100644 video/cirrus.c diff --git a/conf/i386.rmk b/conf/i386.rmk index 02ce39817..ce5d42f0f 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -15,6 +15,11 @@ 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) +pkglib_MODULES += video_cirrus.mod +video_cirrus_mod_SOURCES = video/cirrus.c +video_cirrus_mod_CFLAGS = $(COMMON_CFLAGS) +video_cirrus_mod_LDFLAGS = $(COMMON_LDFLAGS) + pkglib_MODULES += relocator.mod relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S relocator_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/include/grub/video.h b/include/grub/video.h index 5fd7e0c47..08ee54938 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -182,7 +182,8 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_EFI_UGA, GRUB_VIDEO_DRIVER_EFI_GOP, GRUB_VIDEO_DRIVER_SM712, - GRUB_VIDEO_DRIVER_VGA + GRUB_VIDEO_DRIVER_VGA, + GRUB_VIDEO_DRIVER_CIRRUS } grub_video_driver_id_t; struct grub_video_adapter diff --git a/video/cirrus.c b/video/cirrus.c new file mode 100644 index 000000000..ae1bd9940 --- /dev/null +++ b/video/cirrus.c @@ -0,0 +1,538 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct +{ + struct grub_video_mode_info mode_info; + struct grub_video_render_target *render_target; + + grub_uint8_t *ptr; + int mapped; + grub_uint32_t base; + grub_pci_device_t dev; +} framebuffer; + +#define CIRRUS_APERTURE_SIZE 0x200000 + +#define GR_INDEX 0x3ce +#define GR_DATA 0x3cf +#define CR_INDEX 0x3d4 +#define CR_DATA 0x3d5 +#define SR_INDEX 0x3c4 +#define SR_DATA 0x3c5 + +#define CIRRUS_MAX_WIDTH 0x800 +#define CIRRUS_WIDTH_DIVISOR 8 +#define CIRRUS_MAX_HEIGHT 0x800 +#define CIRRUS_MAX_PITCH (0x1ff * CIRRUS_WIDTH_DIVISOR) + +enum + { + CIRRUS_GR_MODE = 5, + CIRRUS_GR_GR6 = 6, + CIRRUS_GR_MAX + }; + +#define CIRRUS_GR_GR6_GRAPHICS_MODE 1 + +#define CIRRUS_GR_MODE_256_COLOR 0x40 +#define CIRRUS_GR_MODE_READ_MODE1 0x08 + +enum + { + CIRRUS_CR_WIDTH = 0x01, + CIRRUS_CR_OVERFLOW = 0x07, + CIRRUS_CR_CELL_HEIGHT = 0x09, + CIRRUS_CR_VSYNC_END = 0x11, + CIRRUS_CR_HEIGHT = 0x12, + CIRRUS_CR_PITCH = 0x13, + CIRRUS_CR_MODE = 0x17, + CIRRUS_CR_LINE_COMPARE = 0x18, + CIRRUS_CR_EXTENDED_DISPLAY = 0x1b, + CIRRUS_CR_MAX + }; + +#define CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40 +#define CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3 + +#define CIRRUS_CR_OVERFLOW_HEIGHT1_SHIFT 7 +#define CIRRUS_CR_OVERFLOW_HEIGHT1_MASK 0x02 +#define CIRRUS_CR_OVERFLOW_HEIGHT2_SHIFT 3 +#define CIRRUS_CR_OVERFLOW_HEIGHT2_MASK 0xc0 +#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK 0x10 +#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_SHIFT 4 + +#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK 0x10 +#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT 4 + +#define CIRRUS_CR_MODE_TIMING_ENABLE 0x80 +#define CIRRUS_CR_MODE_BYTE_MODE 0x40 +#define CIRRUS_CR_MODE_NO_HERCULES 0x02 +#define CIRRUS_CR_MODE_NO_CGA 0x01 + +enum + { + CIRRUS_SR_MEMORY_MODE = 4, + CIRRUS_SR_EXTENDED_MODE = 7, + CIRRUS_SR_MAX + }; +#define CIRRUS_SR_MEMORY_MODE_CHAIN4 8 +#define CIRRUS_SR_MEMORY_MODE_NORMAL 0 +#define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0 +#define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01 +#define CIRRUS_SR_EXTENDED_MODE_24BPP 0x04 +#define CIRRUS_SR_EXTENDED_MODE_16BPP 0x06 +#define CIRRUS_SR_EXTENDED_MODE_32BPP 0x08 + +static void +gr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, GR_INDEX); + grub_outb (val, GR_DATA); +} + +static grub_uint8_t +gr_read (grub_uint8_t addr) +{ + grub_outb (addr, GR_INDEX); + return grub_inb (GR_DATA); +} + +static void +cr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, CR_INDEX); + grub_outb (val, CR_DATA); +} + +static grub_uint8_t +cr_read (grub_uint8_t addr) +{ + grub_outb (addr, CR_INDEX); + return grub_inb (CR_DATA); +} + +static void +sr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, SR_INDEX); + grub_outb (val, SR_DATA); +} + +static grub_uint8_t +sr_read (grub_uint8_t addr) +{ + grub_outb (addr, SR_INDEX); + return grub_inb (SR_DATA); +} + +static void +write_hidden_dac (grub_uint8_t data) +{ + grub_inb (0x3c8); + grub_inb (0x3c6); + grub_inb (0x3c6); + grub_inb (0x3c6); + grub_inb (0x3c6); + grub_outb (data, 0x3c6); +} + +static grub_uint8_t +read_hidden_dac (void) +{ + grub_inb (0x3c8); + grub_inb (0x3c6); + grub_inb (0x3c6); + grub_inb (0x3c6); + grub_inb (0x3c6); + return grub_inb (0x3c6); +} + +struct saved_state +{ + grub_uint8_t cr[CIRRUS_CR_MAX]; + grub_uint8_t gr[CIRRUS_GR_MAX]; + grub_uint8_t sr[CIRRUS_SR_MAX]; + grub_uint8_t hidden_dac; + /* We need to preserve VGA font and VGA text. */ + grub_uint8_t vram[32 * 4 * 256]; +}; + +static struct saved_state initial_state; +static int state_saved = 0; + +static void +save_state (struct saved_state *st) +{ + unsigned i; + for (i = 0; i < ARRAY_SIZE (st->cr); i++) + st->cr[i] = cr_read (i); + for (i = 0; i < ARRAY_SIZE (st->sr); i++) + st->sr[i] = sr_read (i); + for (i = 0; i < ARRAY_SIZE (st->gr); i++) + st->gr[i] = gr_read (i); + st->hidden_dac = read_hidden_dac (); + sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram)); +} + +static void +restore_state (struct saved_state *st) +{ + unsigned i; + sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram)); + for (i = 0; i < ARRAY_SIZE (st->cr); i++) + cr_write (st->cr[i], i); + for (i = 0; i < ARRAY_SIZE (st->sr); i++) + sr_write (st->sr[i], i); + for (i = 0; i < ARRAY_SIZE (st->gr); i++) + gr_write (st->gr[i], i); + write_hidden_dac (st->hidden_dac); +} + +static grub_err_t +grub_video_cirrus_video_init (void) +{ + /* Reset frame buffer. */ + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + + return grub_video_fb_init (); +} + +static grub_err_t +grub_video_cirrus_video_fini (void) +{ + if (framebuffer.mapped) + grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, + CIRRUS_APERTURE_SIZE); + + if (state_saved) + { + restore_state (&initial_state); + state_saved = 0; + } + + return grub_video_fb_fini (); +} + +static grub_err_t +grub_video_cirrus_setup (unsigned int width, unsigned int height, + unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) +{ + int depth; + grub_err_t err; + int found = 0; + int pitch, bytes_per_pixel; + + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x00b81013) + return 0; + + found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + framebuffer.dev = dev; + + return 1; + } + + /* 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; + + if (width == 0 || height == 0) + { + width = 800; + height = 600; + } + + if (width & (CIRRUS_WIDTH_DIVISOR - 1)) + return grub_error (GRUB_ERR_IO, + "screen width must be a multiple of %d", + CIRRUS_WIDTH_DIVISOR); + + if (width > CIRRUS_MAX_WIDTH) + return grub_error (GRUB_ERR_IO, + "screen width must be at most %d", CIRRUS_MAX_WIDTH); + + if (height > CIRRUS_MAX_HEIGHT) + return grub_error (GRUB_ERR_IO, + "screen height must be at most %d", CIRRUS_MAX_HEIGHT); + + if (depth == 0) + depth = 24; + + if (depth != 32 && depth != 24 && depth != 16 && depth != 15) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "only 32, 24, 16 and 15-bit bpp are supported"); + + bytes_per_pixel = (depth + 7) / 8; + pitch = width * bytes_per_pixel; + + if (pitch > CIRRUS_MAX_PITCH) + return grub_error (GRUB_ERR_IO, + "screen width must be at most %d at bitdepth %d", + CIRRUS_MAX_PITCH / bytes_per_pixel, depth); + + grub_pci_iterate (find_card); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + + if (found && framebuffer.base == 0) + { + /* FIXME: change framebuffer base */ + } + + /* We can safely discard volatile attribute. */ + framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, + framebuffer.base, + CIRRUS_APERTURE_SIZE); + framebuffer.mapped = 1; + + if (!state_saved) + { + save_state (&initial_state); + state_saved = 1; + } + + { + int pitch_reg, overflow_reg = 0, line_compare = 0x3ff; + grub_uint8_t sr_ext = 0; + + pitch_reg = pitch / CIRRUS_WIDTH_DIVISOR; + + gr_write (CIRRUS_GR_MODE_256_COLOR | CIRRUS_GR_MODE_READ_MODE1, + CIRRUS_GR_MODE); + gr_write (CIRRUS_GR_GR6_GRAPHICS_MODE, CIRRUS_GR_GR6); + + sr_write (CIRRUS_SR_MEMORY_MODE_NORMAL, CIRRUS_SR_MEMORY_MODE); + + /* Disable CR0-7 write protection. */ + cr_write (0, CIRRUS_CR_VSYNC_END); + + cr_write (width / CIRRUS_WIDTH_DIVISOR - 1, CIRRUS_CR_WIDTH); + cr_write ((height - 1) & 0xff, CIRRUS_CR_HEIGHT); + overflow_reg |= (((height - 1) >> CIRRUS_CR_OVERFLOW_HEIGHT1_SHIFT) & + CIRRUS_CR_OVERFLOW_HEIGHT1_MASK) + | (((height - 1) >> CIRRUS_CR_OVERFLOW_HEIGHT2_SHIFT) & + CIRRUS_CR_OVERFLOW_HEIGHT2_MASK); + + cr_write (pitch_reg & 0xff, CIRRUS_CR_PITCH); + + cr_write (line_compare & 0xff, CIRRUS_CR_LINE_COMPARE); + overflow_reg |= (line_compare >> CIRRUS_CR_OVERFLOW_LINE_COMPARE_SHIFT) + & CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK; + + cr_write (overflow_reg, CIRRUS_CR_OVERFLOW); + + cr_write ((pitch_reg >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT) + & CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK, + CIRRUS_CR_EXTENDED_DISPLAY); + + cr_write ((line_compare >> CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT) + & CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_MASK, CIRRUS_CR_CELL_HEIGHT); + + cr_write (CIRRUS_CR_MODE_TIMING_ENABLE | CIRRUS_CR_MODE_BYTE_MODE + | CIRRUS_CR_MODE_NO_HERCULES | CIRRUS_CR_MODE_NO_CGA, + CIRRUS_CR_MODE); + + sr_ext = CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE + | CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT; + switch (depth) + { + case 32: + sr_ext |= CIRRUS_SR_EXTENDED_MODE_32BPP; + break; + case 24: + sr_ext |= CIRRUS_SR_EXTENDED_MODE_24BPP; + break; + case 16: + case 15: + sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP; + break; + } + sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE); + write_hidden_dac (depth == 16); + } + + /* Fill mode info details. */ + framebuffer.mode_info.width = width; + framebuffer.mode_info.height = height; + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; + framebuffer.mode_info.bpp = depth; + framebuffer.mode_info.bytes_per_pixel = bytes_per_pixel; + framebuffer.mode_info.pitch = pitch; + framebuffer.mode_info.number_of_colors = 256; + framebuffer.mode_info.reserved_mask_size = 0; + framebuffer.mode_info.reserved_field_pos = 0; + + switch (depth) + { + case 16: + framebuffer.mode_info.red_mask_size = 5; + framebuffer.mode_info.red_field_pos = 11; + framebuffer.mode_info.green_mask_size = 6; + framebuffer.mode_info.green_field_pos = 5; + framebuffer.mode_info.blue_mask_size = 5; + framebuffer.mode_info.blue_field_pos = 0; + break; + + case 15: + framebuffer.mode_info.red_mask_size = 5; + framebuffer.mode_info.red_field_pos = 10; + framebuffer.mode_info.green_mask_size = 5; + framebuffer.mode_info.green_field_pos = 5; + framebuffer.mode_info.blue_mask_size = 5; + framebuffer.mode_info.blue_field_pos = 0; + break; + + case 32: + framebuffer.mode_info.reserved_mask_size = 8; + framebuffer.mode_info.reserved_field_pos = 24; + + case 24: + framebuffer.mode_info.red_mask_size = 8; + framebuffer.mode_info.red_field_pos = 16; + framebuffer.mode_info.green_mask_size = 8; + framebuffer.mode_info.green_field_pos = 8; + framebuffer.mode_info.blue_mask_size = 8; + framebuffer.mode_info.blue_field_pos = 0; + break; + } + + framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); + + if (err) + return err; + + err = grub_video_fb_set_active_render_target (framebuffer.render_target); + + if (err) + return err; + + /* Copy default palette to initialize emulated palette. */ + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + return err; +} + +static grub_err_t +grub_video_cirrus_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + /* if (framebuffer.index_color_mode) */ + { + /* TODO: Implement setting indexed color mode palette to hardware. */ + } + + /* Then set color to emulated palette. */ + return grub_video_fb_set_palette (start, count, palette_data); +} + +static grub_err_t +grub_video_cirrus_swap_buffers (void) +{ + /* TODO: Implement buffer swapping. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_cirrus_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + target = framebuffer.render_target; + + return grub_video_fb_set_active_render_target (target); +} + +static grub_err_t +grub_video_cirrus_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf) +{ + grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); + *framebuf = (char *) framebuffer.ptr; + + grub_video_fb_fini (); + + return GRUB_ERR_NONE; +} + + +static struct grub_video_adapter grub_video_cirrus_adapter = + { + .name = "Cirrus CLGD 5446 PCI Video Driver", + .id = GRUB_VIDEO_DRIVER_CIRRUS, + + .init = grub_video_cirrus_video_init, + .fini = grub_video_cirrus_video_fini, + .setup = grub_video_cirrus_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_cirrus_get_info_and_fini, + .set_palette = grub_video_cirrus_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_fb_blit_bitmap, + .blit_render_target = grub_video_fb_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_cirrus_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_cirrus_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(video_cirrus) +{ + grub_video_register (&grub_video_cirrus_adapter); +} + +GRUB_MOD_FINI(video_cirrus) +{ + grub_video_unregister (&grub_video_cirrus_adapter); +} From 26162102fa7cd61a20bc9e637330bdfada6e47a6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 May 2010 14:40:03 +0200 Subject: [PATCH 199/503] Move most framebuffer handling to video_fb.c --- include/grub/video_fb.h | 17 ++- video/fb/video_fb.c | 222 ++++++++++++++++++++++++++++++++++- video/i386/pc/vbe.c | 253 ++++------------------------------------ 3 files changed, 252 insertions(+), 240 deletions(-) diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h index 3046a597b..2c1907fdf 100644 --- a/include/grub/video_fb.h +++ b/include/grub/video_fb.h @@ -119,11 +119,18 @@ typedef grub_err_t (*grub_video_fb_doublebuf_update_screen_t) (struct grub_video_fbrender_target *front, struct grub_video_fbrender_target *back); +typedef grub_err_t (*grub_video_fb_set_page_t) (int page); + grub_err_t -grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, - struct grub_video_fbrender_target **back, - grub_video_fb_doublebuf_update_screen_t *update_screen, - struct grub_video_mode_info mode_info, - void *framebuf); +grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, + struct grub_video_mode_info *mode_info, + volatile void *page0_ptr, + grub_video_fb_set_page_t set_page_in, + volatile void *page1_ptr); +grub_err_t +grub_video_fb_swap_buffers (void); +grub_err_t +grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf); #endif /* ! GRUB_VIDEO_FB_HEADER */ diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 9c5577bb9..6ec61868d 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -26,8 +26,16 @@ #include static struct grub_video_fbrender_target *render_target; +static struct grub_video_fbrender_target *front_target; +static struct grub_video_fbrender_target *back_target; struct grub_video_palette_data *palette; static unsigned int palette_size; +/* For page flipping strategy. */ +static int displayed_page; /* The page # that is the front buffer. */ +static int render_page; /* The page # that is the back buffer. */ +static grub_video_fb_set_page_t set_page; +static char *offscreen_buffer; +static grub_video_fb_doublebuf_update_screen_t update_screen; /* Specify "standard" VGA palette, some video cards may need this and this will also be used when using RGB modes. */ @@ -58,8 +66,11 @@ grub_video_fb_init (void) { grub_free (palette); render_target = 0; + front_target = 0; + back_target = 0; palette = 0; palette_size = 0; + set_page = 0; return GRUB_ERR_NONE; } @@ -68,10 +79,15 @@ grub_video_fb_fini (void) { /* TODO: destroy render targets. */ + grub_free (offscreen_buffer); grub_free (palette); render_target = 0; + front_target = 0; + back_target = 0; palette = 0; palette_size = 0; + set_page = 0; + offscreen_buffer = 0; return GRUB_ERR_NONE; } @@ -1221,6 +1237,10 @@ grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target) grub_err_t grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target) { + if (target == (struct grub_video_fbrender_target *) + GRUB_VIDEO_RENDER_TARGET_DISPLAY) + target = back_target; + if (! target->data) return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid render target given"); @@ -1235,6 +1255,9 @@ grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **targ { *target = render_target; + if (*target == back_target) + *target = (struct grub_video_fbrender_target *) GRUB_VIDEO_RENDER_TARGET_DISPLAY; + return GRUB_ERR_NONE; } @@ -1247,16 +1270,14 @@ doublebuf_blit_update_screen (struct grub_video_fbrender_target *front, return GRUB_ERR_NONE; } -grub_err_t +static grub_err_t grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, struct grub_video_fbrender_target **back, - grub_video_fb_doublebuf_update_screen_t *update_screen, struct grub_video_mode_info mode_info, void *framebuf) { grub_err_t err; int page_size = mode_info.pitch * mode_info.height; - void *offscreen_buffer; err = grub_video_fb_create_render_target_from_pointer (front, &mode_info, framebuf); @@ -1283,7 +1304,200 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, } (*back)->is_allocated = 1; - *update_screen = doublebuf_blit_update_screen; + update_screen = doublebuf_blit_update_screen; + + return GRUB_ERR_NONE; +} + +static grub_err_t +doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front + __attribute__ ((unused)), + struct grub_video_fbrender_target *back + __attribute__ ((unused))) +{ + int new_displayed_page; + struct grub_video_fbrender_target *target; + grub_err_t err; + + /* Swap the page numbers in the framebuffer struct. */ + new_displayed_page = render_page; + render_page = displayed_page; + displayed_page = new_displayed_page; + + err = set_page (displayed_page); + if (err) + { + /* Restore previous state. */ + render_page = displayed_page; + displayed_page = new_displayed_page; + return err; + } + + target = back_target; + back_target = front_target; + front_target = target; + + if (front_target->mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP) + grub_memcpy (back_target->data, front_target->data, + back_target->mode_info.pitch * back_target->mode_info.height); + + err = grub_video_fb_get_active_render_target (&target); + if (err) + return err; + + if (render_target == back_target) + render_target = front_target; + else if (target == front_target) + render_target = back_target; + + return err; +} + +static grub_err_t +doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info, + volatile void *page0_ptr, + grub_video_fb_set_page_t set_page_in, + volatile void *page1_ptr) +{ + grub_err_t err; + + displayed_page = 0; + render_page = 1; + + update_screen = doublebuf_pageflipping_update_screen; + + err = grub_video_fb_create_render_target_from_pointer (&front_target, + mode_info, + (void *) page0_ptr); + if (err) + return err; + + err = grub_video_fb_create_render_target_from_pointer (&back_target, + mode_info, + (void *) page1_ptr); + if (err) + { + grub_video_fb_delete_render_target (front_target); + return err; + } + + /* Set the framebuffer memory data pointer and display the right page. */ + err = set_page_in (displayed_page); + if (err) + { + grub_video_fb_delete_render_target (front_target); + grub_video_fb_delete_render_target (back_target); + return err; + } + set_page = set_page_in; + + return GRUB_ERR_NONE; +} + +/* Select the best double buffering mode available. */ +grub_err_t +grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, + struct grub_video_mode_info *mode_info, + volatile void *page0_ptr, + grub_video_fb_set_page_t set_page_in, + volatile void *page1_ptr) +{ + grub_err_t err; + int updating_swap_needed; + + updating_swap_needed + = grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0); + + /* Do double buffering only if it's either requested or efficient. */ + if (set_page_in && grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, + !updating_swap_needed)) + { + mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + if (updating_swap_needed) + mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP; + + err = doublebuf_pageflipping_init (mode_info, page0_ptr, + set_page_in, + page1_ptr); + if (!err) + { + render_target = back_target; + return GRUB_ERR_NONE; + } + + mode_info->mode_type &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); + + grub_errno = GRUB_ERR_NONE; + } + + if (grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, + 0)) + { + mode_info->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); + + err = grub_video_fb_doublebuf_blit_init (&front_target, + &back_target, + *mode_info, + (void *) page0_ptr); + + if (!err) + { + render_target = back_target; + return GRUB_ERR_NONE; + } + + mode_info->mode_type &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); + + grub_errno = GRUB_ERR_NONE; + } + + /* Fall back to no double buffering. */ + err = grub_video_fb_create_render_target_from_pointer (&front_target, + mode_info, + (void *) page0_ptr); + + if (err) + return err; + + back_target = front_target; + update_screen = 0; + + mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + + render_target = back_target; + + return GRUB_ERR_NONE; +} + + +grub_err_t +grub_video_fb_swap_buffers (void) +{ + grub_err_t err; + if (!update_screen) + return GRUB_ERR_NONE; + + err = update_screen (front_target, back_target); + if (err) + return err; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf) +{ + grub_memcpy (mode_info, &(front_target->mode_info), sizeof (*mode_info)); + *framebuf = front_target->data; + + grub_video_fb_fini (); return GRUB_ERR_NONE; } diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index 72b8f1831..05c6db736 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -40,25 +40,12 @@ static grub_uint32_t last_set_mode = 3; static struct { struct grub_video_mode_info mode_info; - struct grub_video_render_target *front_target; - struct grub_video_render_target *back_target; unsigned int bytes_per_scan_line; unsigned int bytes_per_pixel; grub_uint32_t active_vbe_mode; grub_uint8_t *ptr; int index_color_mode; - - char *offscreen_buffer; - - grub_size_t page_size; /* The size of a page in bytes. */ - - /* For page flipping strategy. */ - int displayed_page; /* The page # that is the front buffer. */ - int render_page; /* The page # that is the back buffer. */ - - /* Virtual functions. */ - grub_video_fb_doublebuf_update_screen_t update_screen; } framebuffer; static grub_uint32_t initial_vbe_mode; @@ -377,7 +364,6 @@ grub_video_vbe_fini (void) vbe_mode_list = NULL; err = grub_video_fb_fini (); - grub_free (framebuffer.offscreen_buffer); return err; } @@ -387,11 +373,11 @@ grub_video_vbe_fini (void) respectively. */ static grub_err_t -doublebuf_pageflipping_commit (void) +doublebuf_pageflipping_set_page (int page) { /* Tell the video adapter to display the new front page. */ int display_start_line - = framebuffer.mode_info.height * framebuffer.displayed_page; + = framebuffer.mode_info.height * page; grub_vbe_status_t vbe_err = grub_vbe_bios_set_display_start (0, display_start_line); @@ -402,164 +388,6 @@ doublebuf_pageflipping_commit (void) return 0; } -static grub_err_t -doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front - __attribute__ ((unused)), - struct grub_video_fbrender_target *back - __attribute__ ((unused))) -{ - int new_displayed_page; - struct grub_video_fbrender_target *target; - grub_err_t err; - - /* Swap the page numbers in the framebuffer struct. */ - new_displayed_page = framebuffer.render_page; - framebuffer.render_page = framebuffer.displayed_page; - framebuffer.displayed_page = new_displayed_page; - - err = doublebuf_pageflipping_commit (); - if (err) - { - /* Restore previous state. */ - framebuffer.render_page = framebuffer.displayed_page; - framebuffer.displayed_page = new_displayed_page; - return err; - } - - if (framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP) - grub_memcpy (framebuffer.ptr + framebuffer.render_page - * framebuffer.page_size, framebuffer.ptr - + framebuffer.displayed_page * framebuffer.page_size, - framebuffer.page_size); - - target = framebuffer.back_target; - framebuffer.back_target = framebuffer.front_target; - framebuffer.front_target = target; - - err = grub_video_fb_get_active_render_target (&target); - if (err) - return err; - - if (target == framebuffer.back_target) - err = grub_video_fb_set_active_render_target (framebuffer.front_target); - else if (target == framebuffer.front_target) - err = grub_video_fb_set_active_render_target (framebuffer.back_target); - - return err; -} - -static grub_err_t -doublebuf_pageflipping_init (void) -{ - /* Get video RAM size in bytes. */ - grub_size_t vram_size = controller_info.total_memory << 16; - grub_err_t err; - - framebuffer.page_size = - framebuffer.mode_info.pitch * framebuffer.mode_info.height; - - if (2 * framebuffer.page_size > vram_size) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Not enough video memory for double buffering."); - - framebuffer.displayed_page = 0; - framebuffer.render_page = 1; - - framebuffer.update_screen = doublebuf_pageflipping_update_screen; - - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr); - if (err) - return err; - - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, &framebuffer.mode_info, framebuffer.ptr + framebuffer.page_size); - if (err) - { - grub_video_fb_delete_render_target (framebuffer.front_target); - return err; - } - - /* Set the framebuffer memory data pointer and display the right page. */ - err = doublebuf_pageflipping_commit (); - if (err) - { - grub_video_fb_delete_render_target (framebuffer.front_target); - grub_video_fb_delete_render_target (framebuffer.back_target); - return err; - } - - return GRUB_ERR_NONE; -} - -/* Select the best double buffering mode available. */ -static grub_err_t -double_buffering_init (unsigned int mode_type, unsigned int mode_mask) -{ - grub_err_t err; - int updating_swap_needed; - - updating_swap_needed - = grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0); - - /* Do double buffering only if it's either requested or efficient. */ - if (grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, - !updating_swap_needed)) - { - framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - if (updating_swap_needed) - framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP; - err = doublebuf_pageflipping_init (); - if (!err) - return GRUB_ERR_NONE; - - framebuffer.mode_info.mode_type - &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - - grub_errno = GRUB_ERR_NONE; - } - - if (grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, - 0)) - { - framebuffer.mode_info.mode_type - |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - - err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target, - &framebuffer.back_target, - &framebuffer.update_screen, - framebuffer.mode_info, - framebuffer.ptr); - - if (!err) - return GRUB_ERR_NONE; - - framebuffer.mode_info.mode_type - &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - - grub_errno = GRUB_ERR_NONE; - } - - /* Fall back to no double buffering. */ - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr); - - if (err) - return err; - - framebuffer.back_target = framebuffer.front_target; - framebuffer.update_screen = 0; - - framebuffer.mode_info.mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - - return GRUB_ERR_NONE; -} - - - static grub_err_t grub_video_vbe_setup (unsigned int width, unsigned int height, unsigned int mode_type, unsigned int mode_mask) @@ -684,15 +512,24 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - /* Set up double buffering and targets. */ - err = double_buffering_init (mode_type, mode_mask); - if (err) - return err; + { + /* Get video RAM size in bytes. */ + grub_size_t vram_size = controller_info.total_memory << 16; + grub_size_t page_size; /* The size of a page in bytes. */ - err = grub_video_fb_set_active_render_target (framebuffer.back_target); + page_size = framebuffer.mode_info.pitch * framebuffer.mode_info.height; - if (err) - return err; + if (vram_size >= 2 * page_size) + err = grub_video_fb_setup (mode_type, mode_mask, + &framebuffer.mode_info, + framebuffer.ptr, + doublebuf_pageflipping_set_page, + framebuffer.ptr + page_size); + else + err = grub_video_fb_setup (mode_type, mode_mask, + &framebuffer.mode_info, + framebuffer.ptr, 0, 0); + } /* Copy default palette to initialize emulated palette. */ err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, @@ -723,59 +560,13 @@ grub_video_vbe_set_palette (unsigned int start, unsigned int count, return grub_video_fb_set_palette (start, count, palette_data); } -static grub_err_t -grub_video_vbe_swap_buffers (void) -{ - grub_err_t err; - if (!framebuffer.update_screen) - return GRUB_ERR_NONE; - - err = framebuffer.update_screen (framebuffer.front_target, - framebuffer.back_target); - if (err) - return err; - - 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_DISPLAY) - target = framebuffer.back_target; - - return grub_video_fb_set_active_render_target (target); -} - -static grub_err_t -grub_video_vbe_get_active_render_target (struct grub_video_render_target **target) -{ - grub_err_t err; - err = grub_video_fb_get_active_render_target (target); - if (err) - return err; - - if (*target == framebuffer.back_target) - *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY; - - return GRUB_ERR_NONE; -} - static grub_err_t grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, void **framebuf) { - grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); - *framebuf = (char *) framebuffer.ptr - + framebuffer.displayed_page * framebuffer.page_size; - grub_free (vbe_mode_list); vbe_mode_list = NULL; - - grub_video_fb_fini (); - grub_free (framebuffer.offscreen_buffer); - - return GRUB_ERR_NONE; + return grub_video_fb_get_info_and_fini (mode_info, framebuf); } static struct grub_video_adapter grub_video_vbe_adapter = @@ -800,11 +591,11 @@ static struct grub_video_adapter grub_video_vbe_adapter = .blit_bitmap = grub_video_fb_blit_bitmap, .blit_render_target = grub_video_fb_blit_render_target, .scroll = grub_video_fb_scroll, - .swap_buffers = grub_video_vbe_swap_buffers, + .swap_buffers = grub_video_fb_swap_buffers, .create_render_target = grub_video_fb_create_render_target, .delete_render_target = grub_video_fb_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, + .set_active_render_target = grub_video_fb_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, .next = 0 }; From 02aabd9e467744b696878db42adc0acd5a900609 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 May 2010 15:01:54 +0200 Subject: [PATCH 200/503] Encapsulate video_fb state in a structure --- include/grub/video_fb.h | 4 +- video/fb/video_fb.c | 398 ++++++++++++++++++++-------------------- 2 files changed, 206 insertions(+), 196 deletions(-) diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h index 2c1907fdf..6816f6f60 100644 --- a/include/grub/video_fb.h +++ b/include/grub/video_fb.h @@ -89,8 +89,8 @@ grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap, grub_err_t grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source, - enum grub_video_blit_operators oper, - int x, int y, int offset_x, int offset_y, + 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 diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 6ec61868d..69626be5c 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -25,17 +25,20 @@ #include #include -static struct grub_video_fbrender_target *render_target; -static struct grub_video_fbrender_target *front_target; -static struct grub_video_fbrender_target *back_target; -struct grub_video_palette_data *palette; -static unsigned int palette_size; -/* For page flipping strategy. */ -static int displayed_page; /* The page # that is the front buffer. */ -static int render_page; /* The page # that is the back buffer. */ -static grub_video_fb_set_page_t set_page; -static char *offscreen_buffer; -static grub_video_fb_doublebuf_update_screen_t update_screen; +static struct +{ + struct grub_video_fbrender_target *render_target; + struct grub_video_fbrender_target *front_target; + struct grub_video_fbrender_target *back_target; + struct grub_video_palette_data *palette; + unsigned int palette_size; + /* For page flipping strategy. */ + int displayed_page; /* The page # that is the front buffer. */ + int render_page; /* The page # that is the back buffer. */ + grub_video_fb_set_page_t set_page; + char *offscreen_buffer; + grub_video_fb_doublebuf_update_screen_t update_screen; +} framebuffer; /* Specify "standard" VGA palette, some video cards may need this and this will also be used when using RGB modes. */ @@ -64,13 +67,13 @@ struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLOR grub_err_t grub_video_fb_init (void) { - grub_free (palette); - render_target = 0; - front_target = 0; - back_target = 0; - palette = 0; - palette_size = 0; - set_page = 0; + grub_free (framebuffer.palette); + framebuffer.render_target = 0; + framebuffer.front_target = 0; + framebuffer.back_target = 0; + framebuffer.palette = 0; + framebuffer.palette_size = 0; + framebuffer.set_page = 0; return GRUB_ERR_NONE; } @@ -79,15 +82,15 @@ grub_video_fb_fini (void) { /* TODO: destroy render targets. */ - grub_free (offscreen_buffer); - grub_free (palette); - render_target = 0; - front_target = 0; - back_target = 0; - palette = 0; - palette_size = 0; - set_page = 0; - offscreen_buffer = 0; + grub_free (framebuffer.offscreen_buffer); + grub_free (framebuffer.palette); + framebuffer.render_target = 0; + framebuffer.front_target = 0; + framebuffer.back_target = 0; + framebuffer.palette = 0; + framebuffer.palette_size = 0; + framebuffer.set_page = 0; + framebuffer.offscreen_buffer = 0; return GRUB_ERR_NONE; } @@ -95,7 +98,7 @@ grub_err_t grub_video_fb_get_info (struct grub_video_mode_info *mode_info) { /* Copy mode info from active render target. */ - grub_memcpy (mode_info, &render_target->mode_info, + grub_memcpy (mode_info, &framebuffer.render_target->mode_info, sizeof (struct grub_video_mode_info)); return GRUB_ERR_NONE; @@ -108,8 +111,8 @@ grub_video_fb_get_palette (unsigned int start, unsigned int count, unsigned int i; /* Assume that we know everything from index color palette. */ - for (i = 0; (i < count) && ((i + start) < palette_size); i++) - palette_data[i] = palette[start + i]; + for (i = 0; (i < count) && ((i + start) < framebuffer.palette_size); i++) + palette_data[i] = framebuffer.palette[start + i]; return GRUB_ERR_NONE; } @@ -119,18 +122,20 @@ grub_video_fb_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data) { unsigned i; - if (start + count > palette_size) + if (start + count > framebuffer.palette_size) { - palette_size = start + count; - palette = grub_realloc (palette, sizeof (palette[0]) * palette_size); - if (!palette) + framebuffer.palette_size = start + count; + framebuffer.palette = grub_realloc (framebuffer.palette, + sizeof (framebuffer.palette[0]) + * framebuffer.palette_size); + if (!framebuffer.palette) { grub_video_fb_fini (); return grub_errno; } } - for (i = 0; (i < count) && ((i + start) < palette_size); i++) - palette[start + i] = palette_data[i]; + for (i = 0; (i < count) && ((i + start) < framebuffer.palette_size); i++) + framebuffer.palette[start + i] = palette_data[i]; return GRUB_ERR_NONE; } @@ -140,28 +145,28 @@ grub_video_fb_set_viewport (unsigned int x, unsigned int y, { /* Make sure viewport is withing screen dimensions. If viewport was set to be out of the region, mark its size as zero. */ - if (x > render_target->mode_info.width) + if (x > framebuffer.render_target->mode_info.width) { x = 0; width = 0; } - if (y > render_target->mode_info.height) + if (y > framebuffer.render_target->mode_info.height) { y = 0; height = 0; } - if (x + width > render_target->mode_info.width) - width = render_target->mode_info.width - x; + if (x + width > framebuffer.render_target->mode_info.width) + width = framebuffer.render_target->mode_info.width - x; - if (y + height > render_target->mode_info.height) - height = render_target->mode_info.height - y; + if (y + height > framebuffer.render_target->mode_info.height) + height = framebuffer.render_target->mode_info.height - y; - render_target->viewport.x = x; - render_target->viewport.y = y; - render_target->viewport.width = width; - render_target->viewport.height = height; + framebuffer.render_target->viewport.x = x; + framebuffer.render_target->viewport.y = y; + framebuffer.render_target->viewport.width = width; + framebuffer.render_target->viewport.height = height; return GRUB_ERR_NONE; } @@ -170,10 +175,10 @@ grub_err_t grub_video_fb_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; + if (x) *x = framebuffer.render_target->viewport.x; + if (y) *y = framebuffer.render_target->viewport.y; + if (width) *width = framebuffer.render_target->viewport.width; + if (height) *height = framebuffer.render_target->viewport.height; return GRUB_ERR_NONE; } @@ -184,18 +189,18 @@ grub_video_fb_map_color (grub_uint32_t color_name) { /* TODO: implement color theme mapping code. */ - if (color_name < palette_size) + if (color_name < framebuffer.palette_size) { - if ((render_target->mode_info.mode_type + if ((framebuffer.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_fb_map_rgb (palette[color_name].r, - palette[color_name].g, - palette[color_name].b); + color = grub_video_fb_map_rgb (framebuffer.palette[color_name].r, + framebuffer.palette[color_name].g, + framebuffer.palette[color_name].b); return color; } @@ -209,7 +214,7 @@ grub_video_color_t grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue) { - if ((render_target->mode_info.mode_type + if ((framebuffer.render_target->mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) { int minindex = 0; @@ -219,13 +224,13 @@ grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green, unsigned i; /* Find best matching color. */ - for (i = 0; i < palette_size; i++) + for (i = 0; i < framebuffer.palette_size; i++) { - val = palette[i].r - red; + val = framebuffer.palette[i].r - red; tmp = val * val; - val = palette[i].g - green; + val = framebuffer.palette[i].g - green; tmp += val * val; - val = palette[i].b - blue; + val = framebuffer.palette[i].b - blue; tmp += val * val; if (i == 0) @@ -242,12 +247,12 @@ grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green, return minindex; } - else if ((render_target->mode_info.mode_type + else if ((framebuffer.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) + if (red == framebuffer.render_target->mode_info.fg_red + && green == framebuffer.render_target->mode_info.fg_green + && blue == framebuffer.render_target->mode_info.fg_blue) return 1; else return 0; @@ -257,15 +262,15 @@ grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green, 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; + red >>= 8 - framebuffer.render_target->mode_info.red_mask_size; + green >>= 8 - framebuffer.render_target->mode_info.green_mask_size; + blue >>= 8 - framebuffer.render_target->mode_info.blue_mask_size; + alpha >>= 8 - framebuffer.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; + value = red << framebuffer.render_target->mode_info.red_field_pos; + value |= green << framebuffer.render_target->mode_info.green_field_pos; + value |= blue << framebuffer.render_target->mode_info.blue_field_pos; + value |= alpha << framebuffer.render_target->mode_info.reserved_field_pos; return value; } @@ -277,18 +282,18 @@ grub_video_color_t grub_video_fb_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 + if ((framebuffer.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_fb_map_rgb (red, green, blue); - else if ((render_target->mode_info.mode_type + else if ((framebuffer.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) + if (red == framebuffer.render_target->mode_info.fg_red + && green == framebuffer.render_target->mode_info.fg_green + && blue == framebuffer.render_target->mode_info.fg_blue + && alpha == framebuffer.render_target->mode_info.fg_alpha) return 1; else return 0; @@ -297,15 +302,15 @@ grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green, { 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; + red >>= 8 - framebuffer.render_target->mode_info.red_mask_size; + green >>= 8 - framebuffer.render_target->mode_info.green_mask_size; + blue >>= 8 - framebuffer.render_target->mode_info.blue_mask_size; + alpha >>= 8 - framebuffer.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; + value = red << framebuffer.render_target->mode_info.red_field_pos; + value |= green << framebuffer.render_target->mode_info.green_field_pos; + value |= blue << framebuffer.render_target->mode_info.blue_field_pos; + value |= alpha << framebuffer.render_target->mode_info.reserved_field_pos; return value; } @@ -319,8 +324,8 @@ grub_video_fb_unmap_color (grub_video_color_t color, { struct grub_video_fbblit_info target_info; - target_info.mode_info = &render_target->mode_info; - target_info.data = render_target->data; + target_info.mode_info = &framebuffer.render_target->mode_info; + target_info.data = framebuffer.render_target->data; grub_video_fb_unmap_color_int (&target_info, color, red, green, blue, alpha); @@ -350,10 +355,10 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source, return; } - *red = palette[color].r; - *green = palette[color].g; - *blue = palette[color].b; - *alpha = palette[color].a; + *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 @@ -422,9 +427,9 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y, struct grub_video_fbblit_info target; /* Make sure there is something to do. */ - if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0)) + if ((x >= (int)framebuffer.render_target->viewport.width) || (x + (int)width < 0)) return GRUB_ERR_NONE; - if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + if ((y >= (int)framebuffer.render_target->viewport.height) || (y + (int)height < 0)) return GRUB_ERR_NONE; /* Do not allow drawing out of viewport. */ @@ -439,18 +444,18 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int 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; + if ((x + width) > framebuffer.render_target->viewport.width) + width = framebuffer.render_target->viewport.width - x; + if ((y + height) > framebuffer.render_target->viewport.height) + height = framebuffer.render_target->viewport.height - y; /* Add viewport offset. */ - x += render_target->viewport.x; - y += render_target->viewport.y; + x += framebuffer.render_target->viewport.x; + y += framebuffer.render_target->viewport.y; /* Use fbblit_info to encapsulate rendering. */ - target.mode_info = &render_target->mode_info; - target.data = render_target->data; + target.mode_info = &framebuffer.render_target->mode_info; + target.data = framebuffer.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. */ @@ -777,9 +782,9 @@ grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap, /* 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)) + if ((x >= (int)framebuffer.render_target->viewport.width) || (x + (int)width < 0)) return GRUB_ERR_NONE; - if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + if ((y >= (int)framebuffer.render_target->viewport.height) || (y + (int)height < 0)) return GRUB_ERR_NONE; if ((x + (int)bitmap->mode_info.width) < 0) return GRUB_ERR_NONE; @@ -822,10 +827,10 @@ grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap, } /* 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 ((x + width) > framebuffer.render_target->viewport.width) + width = framebuffer.render_target->viewport.width - x; + if ((y + height) > framebuffer.render_target->viewport.height) + height = framebuffer.render_target->viewport.height - y; if ((offset_x + width) > bitmap->mode_info.width) width = bitmap->mode_info.width - offset_x; @@ -840,14 +845,14 @@ grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap, height = bitmap->mode_info.height; /* Add viewport offset. */ - x += render_target->viewport.x; - y += render_target->viewport.y; + x += framebuffer.render_target->viewport.x; + y += framebuffer.render_target->viewport.y; /* Use fbblit_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; + target.mode_info = &framebuffer.render_target->mode_info; + target.data = framebuffer.render_target->data; /* Do actual blitting. */ common_blitter (&target, &source, oper, x, y, width, height, @@ -868,9 +873,9 @@ grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source, /* 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)) + if ((x >= (int)framebuffer.render_target->viewport.width) || (x + (int)width < 0)) return GRUB_ERR_NONE; - if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + if ((y >= (int)framebuffer.render_target->viewport.height) || (y + (int)height < 0)) return GRUB_ERR_NONE; if ((x + (int)source->mode_info.width) < 0) return GRUB_ERR_NONE; @@ -913,10 +918,10 @@ grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source, } /* 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 ((x + width) > framebuffer.render_target->viewport.width) + width = framebuffer.render_target->viewport.width - x; + if ((y + height) > framebuffer.render_target->viewport.height) + height = framebuffer.render_target->viewport.height - y; if ((offset_x + width) > source->mode_info.width) width = source->mode_info.width - offset_x; @@ -931,14 +936,14 @@ grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source, height = source->mode_info.height; /* Add viewport offset. */ - x += render_target->viewport.x; - y += render_target->viewport.y; + x += framebuffer.render_target->viewport.x; + y += framebuffer.render_target->viewport.y; /* Use fbblit_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; + target_info.mode_info = &framebuffer.render_target->mode_info; + target_info.data = framebuffer.render_target->data; /* Do actual blitting. */ common_blitter (&target_info, &source_info, oper, x, y, width, height, @@ -961,42 +966,42 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) 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); + width = framebuffer.render_target->viewport.width - grub_abs (dx); + height = framebuffer.render_target->viewport.height - grub_abs (dy); if (dx < 0) { - src_x = render_target->viewport.x - dx; - dst_x = render_target->viewport.x; + src_x = framebuffer.render_target->viewport.x - dx; + dst_x = framebuffer.render_target->viewport.x; } else { - src_x = render_target->viewport.x; - dst_x = render_target->viewport.x + dx; + src_x = framebuffer.render_target->viewport.x; + dst_x = framebuffer.render_target->viewport.x + dx; } if (dy < 0) { - src_y = render_target->viewport.y - dy; - dst_y = render_target->viewport.y; + src_y = framebuffer.render_target->viewport.y - dy; + dst_y = framebuffer.render_target->viewport.y; } else { - src_y = render_target->viewport.y; - dst_y = render_target->viewport.y + dy; + src_y = framebuffer.render_target->viewport.y; + dst_y = framebuffer.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)) + if ((grub_abs (dx) < framebuffer.render_target->viewport.width) + && (grub_abs (dy) < framebuffer.render_target->viewport.height)) { /* 3. Move data in render target. */ struct grub_video_fbblit_info target; int i, j; int linedelta, linelen; - target.mode_info = &render_target->mode_info; - target.data = render_target->data; + target.mode_info = &framebuffer.render_target->mode_info; + target.data = framebuffer.render_target->data; linedelta = target.mode_info->pitch - width * target.mode_info->bytes_per_pixel; @@ -1079,27 +1084,27 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) /* 4a. Fill top & bottom parts. */ if (dy > 0) - grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy); + grub_video_fb_fill_rect (color, 0, 0, framebuffer.render_target->viewport.width, dy); else if (dy < 0) { - if (render_target->viewport.height < grub_abs (dy)) - dy = -render_target->viewport.height; + if (framebuffer.render_target->viewport.height < grub_abs (dy)) + dy = -framebuffer.render_target->viewport.height; - grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy, - render_target->viewport.width, -dy); + grub_video_fb_fill_rect (color, 0, framebuffer.render_target->viewport.height + dy, + framebuffer.render_target->viewport.width, -dy); } /* 4b. Fill left & right parts. */ if (dx > 0) grub_video_fb_fill_rect (color, 0, 0, - dx, render_target->viewport.height); + dx, framebuffer.render_target->viewport.height); else if (dx < 0) { - if (render_target->viewport.width < grub_abs (dx)) - dx = -render_target->viewport.width; + if (framebuffer.render_target->viewport.width < grub_abs (dx)) + dx = -framebuffer.render_target->viewport.width; - grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0, - -dx, render_target->viewport.height); + grub_video_fb_fill_rect (color, framebuffer.render_target->viewport.width + dx, 0, + -dx, framebuffer.render_target->viewport.height); } return GRUB_ERR_NONE; @@ -1146,7 +1151,7 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result, 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 = palette_size; /* Emulated palette. */ + target->mode_info.number_of_colors = framebuffer.palette_size; /* Emulated palette. */ target->mode_info.red_mask_size = 8; target->mode_info.red_field_pos = 0; target->mode_info.green_mask_size = 8; @@ -1239,13 +1244,13 @@ grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *targe { if (target == (struct grub_video_fbrender_target *) GRUB_VIDEO_RENDER_TARGET_DISPLAY) - target = back_target; + target = framebuffer.back_target; if (! target->data) return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid render target given"); - render_target = target; + framebuffer.render_target = target; return GRUB_ERR_NONE; } @@ -1253,9 +1258,9 @@ grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *targe grub_err_t grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target) { - *target = render_target; + *target = framebuffer.render_target; - if (*target == back_target) + if (*target == framebuffer.back_target) *target = (struct grub_video_fbrender_target *) GRUB_VIDEO_RENDER_TARGET_DISPLAY; return GRUB_ERR_NONE; @@ -1284,8 +1289,8 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, if (err) return err; - offscreen_buffer = grub_malloc (page_size); - if (! offscreen_buffer) + framebuffer.offscreen_buffer = grub_malloc (page_size); + if (! framebuffer.offscreen_buffer) { grub_video_fb_delete_render_target (*front); *front = 0; @@ -1293,18 +1298,19 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, } err = grub_video_fb_create_render_target_from_pointer (back, &mode_info, - offscreen_buffer); + framebuffer.offscreen_buffer); if (err) { grub_video_fb_delete_render_target (*front); - grub_free (offscreen_buffer); + grub_free (framebuffer.offscreen_buffer); + framebuffer.offscreen_buffer = 0; *front = 0; return grub_errno; } (*back)->is_allocated = 1; - update_screen = doublebuf_blit_update_screen; + framebuffer.update_screen = doublebuf_blit_update_screen; return GRUB_ERR_NONE; } @@ -1320,35 +1326,37 @@ doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front grub_err_t err; /* Swap the page numbers in the framebuffer struct. */ - new_displayed_page = render_page; - render_page = displayed_page; - displayed_page = new_displayed_page; + new_displayed_page = framebuffer.render_page; + framebuffer.render_page = framebuffer.displayed_page; + framebuffer.displayed_page = new_displayed_page; - err = set_page (displayed_page); + err = framebuffer.set_page (framebuffer.displayed_page); if (err) { /* Restore previous state. */ - render_page = displayed_page; - displayed_page = new_displayed_page; + framebuffer.render_page = framebuffer.displayed_page; + framebuffer.displayed_page = new_displayed_page; return err; } - target = back_target; - back_target = front_target; - front_target = target; + target = framebuffer.back_target; + framebuffer.back_target = framebuffer.front_target; + framebuffer.front_target = target; - if (front_target->mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP) - grub_memcpy (back_target->data, front_target->data, - back_target->mode_info.pitch * back_target->mode_info.height); + if (framebuffer.front_target->mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP) + grub_memcpy (framebuffer.back_target->data, framebuffer.front_target->data, + framebuffer.back_target->mode_info.pitch + * framebuffer.back_target->mode_info.height); err = grub_video_fb_get_active_render_target (&target); if (err) return err; - if (render_target == back_target) - render_target = front_target; - else if (target == front_target) - render_target = back_target; + if (framebuffer.render_target == framebuffer.back_target) + framebuffer.render_target = framebuffer.front_target; + else if (framebuffer.render_target == framebuffer.front_target) + framebuffer.render_target = framebuffer.back_target; return err; } @@ -1361,35 +1369,35 @@ doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info, { grub_err_t err; - displayed_page = 0; - render_page = 1; + framebuffer.displayed_page = 0; + framebuffer.render_page = 1; - update_screen = doublebuf_pageflipping_update_screen; + framebuffer.update_screen = doublebuf_pageflipping_update_screen; - err = grub_video_fb_create_render_target_from_pointer (&front_target, + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, mode_info, (void *) page0_ptr); if (err) return err; - err = grub_video_fb_create_render_target_from_pointer (&back_target, + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, mode_info, (void *) page1_ptr); if (err) { - grub_video_fb_delete_render_target (front_target); + grub_video_fb_delete_render_target (framebuffer.front_target); return err; } /* Set the framebuffer memory data pointer and display the right page. */ - err = set_page_in (displayed_page); + err = set_page_in (framebuffer.displayed_page); if (err) { - grub_video_fb_delete_render_target (front_target); - grub_video_fb_delete_render_target (back_target); + grub_video_fb_delete_render_target (framebuffer.front_target); + grub_video_fb_delete_render_target (framebuffer.back_target); return err; } - set_page = set_page_in; + framebuffer.set_page = set_page_in; return GRUB_ERR_NONE; } @@ -1423,7 +1431,7 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, page1_ptr); if (!err) { - render_target = back_target; + framebuffer.render_target = framebuffer.back_target; return GRUB_ERR_NONE; } @@ -1440,14 +1448,14 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, mode_info->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - err = grub_video_fb_doublebuf_blit_init (&front_target, - &back_target, + err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target, + &framebuffer.back_target, *mode_info, (void *) page0_ptr); if (!err) { - render_target = back_target; + framebuffer.render_target = framebuffer.back_target; return GRUB_ERR_NONE; } @@ -1458,19 +1466,19 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, } /* Fall back to no double buffering. */ - err = grub_video_fb_create_render_target_from_pointer (&front_target, + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, mode_info, (void *) page0_ptr); if (err) return err; - back_target = front_target; - update_screen = 0; + framebuffer.back_target = framebuffer.front_target; + framebuffer.update_screen = 0; mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - render_target = back_target; + framebuffer.render_target = framebuffer.back_target; return GRUB_ERR_NONE; } @@ -1480,10 +1488,11 @@ grub_err_t grub_video_fb_swap_buffers (void) { grub_err_t err; - if (!update_screen) + if (!framebuffer.update_screen) return GRUB_ERR_NONE; - err = update_screen (front_target, back_target); + err = framebuffer.update_screen (framebuffer.front_target, + framebuffer.back_target); if (err) return err; @@ -1494,8 +1503,9 @@ grub_err_t grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info, void **framebuf) { - grub_memcpy (mode_info, &(front_target->mode_info), sizeof (*mode_info)); - *framebuf = front_target->data; + grub_memcpy (mode_info, &(framebuffer.front_target->mode_info), + sizeof (*mode_info)); + *framebuf = framebuffer.front_target->data; grub_video_fb_fini (); From d00b0b3f4d25e0945d1aadb59afa1752b43b680a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 May 2010 20:20:31 +0200 Subject: [PATCH 201/503] Support double buffering on video cirrus --- video/cirrus.c | 108 +++++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 44 deletions(-) diff --git a/video/cirrus.c b/video/cirrus.c index ae1bd9940..09dbb2c1d 100644 --- a/video/cirrus.c +++ b/video/cirrus.c @@ -30,7 +30,7 @@ static struct { struct grub_video_mode_info mode_info; - struct grub_video_render_target *render_target; + grub_size_t page_size; /* The size of a page in bytes. */ grub_uint8_t *ptr; int mapped; @@ -69,12 +69,15 @@ enum CIRRUS_CR_WIDTH = 0x01, CIRRUS_CR_OVERFLOW = 0x07, CIRRUS_CR_CELL_HEIGHT = 0x09, + CIRRUS_CR_SCREEN_START_HIGH = 0xc, + CIRRUS_CR_SCREEN_START_LOW = 0xd, CIRRUS_CR_VSYNC_END = 0x11, CIRRUS_CR_HEIGHT = 0x12, CIRRUS_CR_PITCH = 0x13, CIRRUS_CR_MODE = 0x17, CIRRUS_CR_LINE_COMPARE = 0x18, CIRRUS_CR_EXTENDED_DISPLAY = 0x1b, + CIRRUS_CR_EXTENDED_OVERLAY = 0x1d, CIRRUS_CR_MAX }; @@ -85,17 +88,25 @@ enum #define CIRRUS_CR_OVERFLOW_HEIGHT1_MASK 0x02 #define CIRRUS_CR_OVERFLOW_HEIGHT2_SHIFT 3 #define CIRRUS_CR_OVERFLOW_HEIGHT2_MASK 0xc0 -#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK 0x10 #define CIRRUS_CR_OVERFLOW_LINE_COMPARE_SHIFT 4 - -#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK 0x10 -#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT 4 +#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK 0x10 #define CIRRUS_CR_MODE_TIMING_ENABLE 0x80 #define CIRRUS_CR_MODE_BYTE_MODE 0x40 #define CIRRUS_CR_MODE_NO_HERCULES 0x02 #define CIRRUS_CR_MODE_NO_CGA 0x01 +#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK 0x10 +#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT 4 +#define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 0x1 +#define CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT1 16 +#define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2 0xc +#define CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT2 15 + +#define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK 0x80 +#define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT 12 + + enum { CIRRUS_SR_MEMORY_MODE = 4, @@ -242,6 +253,33 @@ grub_video_cirrus_video_fini (void) return grub_video_fb_fini (); } +static grub_err_t +doublebuf_pageflipping_set_page (int page) +{ + int start = framebuffer.page_size * page / 4; + grub_uint8_t cr_ext, cr_overlay; + + cr_write (start & 0xff, CIRRUS_CR_SCREEN_START_LOW); + cr_write ((start & 0xff00) >> 8, CIRRUS_CR_SCREEN_START_HIGH); + + cr_ext = cr_read (CIRRUS_CR_EXTENDED_DISPLAY); + cr_ext &= ~(CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 + | CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2); + cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT1) + & CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1); + cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT2) + & CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2); + cr_write (cr_ext, CIRRUS_CR_EXTENDED_DISPLAY); + + cr_overlay = cr_read (CIRRUS_CR_EXTENDED_OVERLAY); + cr_overlay &= ~(CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK); + cr_overlay |= ((start >> CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT) + & CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK); + cr_write (cr_overlay, CIRRUS_CR_EXTENDED_OVERLAY); + + return GRUB_ERR_NONE; +} + static grub_err_t grub_video_cirrus_setup (unsigned int width, unsigned int height, unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) @@ -310,6 +348,11 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, "screen width must be at most %d at bitdepth %d", CIRRUS_MAX_PITCH / bytes_per_pixel, depth); + framebuffer.page_size = pitch * height; + + if (framebuffer.page_size > CIRRUS_APERTURE_SIZE) + return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); + grub_pci_iterate (find_card); if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); @@ -317,6 +360,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, if (found && framebuffer.base == 0) { /* FIXME: change framebuffer base */ + return grub_error (GRUB_ERR_IO, "PCI BAR not set"); } /* We can safely discard volatile attribute. */ @@ -372,6 +416,8 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, | CIRRUS_CR_MODE_NO_HERCULES | CIRRUS_CR_MODE_NO_CGA, CIRRUS_CR_MODE); + doublebuf_pageflipping_set_page (0); + sr_ext = CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE | CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT; switch (depth) @@ -438,15 +484,17 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); + if (CIRRUS_APERTURE_SIZE >= 2 * framebuffer.page_size) + err = grub_video_fb_setup (mode_type, mode_mask, + &framebuffer.mode_info, + framebuffer.ptr, + doublebuf_pageflipping_set_page, + framebuffer.ptr + framebuffer.page_size); + else + err = grub_video_fb_setup (mode_type, mode_mask, + &framebuffer.mode_info, + framebuffer.ptr, 0, 0); - if (err) - return err; - - err = grub_video_fb_set_active_render_target (framebuffer.render_target); - - if (err) - return err; /* Copy default palette to initialize emulated palette. */ err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, @@ -467,34 +515,6 @@ grub_video_cirrus_set_palette (unsigned int start, unsigned int count, return grub_video_fb_set_palette (start, count, palette_data); } -static grub_err_t -grub_video_cirrus_swap_buffers (void) -{ - /* TODO: Implement buffer swapping. */ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_cirrus_set_active_render_target (struct grub_video_render_target *target) -{ - if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) - target = framebuffer.render_target; - - return grub_video_fb_set_active_render_target (target); -} - -static grub_err_t -grub_video_cirrus_get_info_and_fini (struct grub_video_mode_info *mode_info, - void **framebuf) -{ - grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); - *framebuf = (char *) framebuffer.ptr; - - grub_video_fb_fini (); - - return GRUB_ERR_NONE; -} - static struct grub_video_adapter grub_video_cirrus_adapter = { @@ -505,7 +525,7 @@ static struct grub_video_adapter grub_video_cirrus_adapter = .fini = grub_video_cirrus_video_fini, .setup = grub_video_cirrus_setup, .get_info = grub_video_fb_get_info, - .get_info_and_fini = grub_video_cirrus_get_info_and_fini, + .get_info_and_fini = grub_video_fb_get_info_and_fini, .set_palette = grub_video_cirrus_set_palette, .get_palette = grub_video_fb_get_palette, .set_viewport = grub_video_fb_set_viewport, @@ -518,10 +538,10 @@ static struct grub_video_adapter grub_video_cirrus_adapter = .blit_bitmap = grub_video_fb_blit_bitmap, .blit_render_target = grub_video_fb_blit_render_target, .scroll = grub_video_fb_scroll, - .swap_buffers = grub_video_cirrus_swap_buffers, + .swap_buffers = grub_video_fb_swap_buffers, .create_render_target = grub_video_fb_create_render_target, .delete_render_target = grub_video_fb_delete_render_target, - .set_active_render_target = grub_video_cirrus_set_active_render_target, + .set_active_render_target = grub_video_fb_set_active_render_target, .get_active_render_target = grub_video_fb_get_active_render_target, .next = 0 From 63c1b71cbbbc6468fb98ca63dd4248398fe254d9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 May 2010 20:44:44 +0200 Subject: [PATCH 202/503] Cleanup hidden DAC part. --- video/cirrus.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/video/cirrus.c b/video/cirrus.c index 09dbb2c1d..2e487311e 100644 --- a/video/cirrus.c +++ b/video/cirrus.c @@ -121,6 +121,15 @@ enum #define CIRRUS_SR_EXTENDED_MODE_16BPP 0x06 #define CIRRUS_SR_EXTENDED_MODE_32BPP 0x08 +#define CIRRUS_HIDDEN_DAC_ENABLE_EXT 0x80 +#define CIRRUS_HIDDEN_DAC_ENABLE_ALL 0x40 +#define CIRRUS_HIDDEN_DAC_15BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ + | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 0) +#define CIRRUS_HIDDEN_DAC_16BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ + | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 1) +#define CIRRUS_HIDDEN_DAC_888COLOR (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ + | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 5) + static void gr_write (grub_uint8_t val, grub_uint8_t addr) { @@ -377,7 +386,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, { int pitch_reg, overflow_reg = 0, line_compare = 0x3ff; - grub_uint8_t sr_ext = 0; + grub_uint8_t sr_ext = 0, hidden_dac = 0; pitch_reg = pitch / CIRRUS_WIDTH_DIVISOR; @@ -422,19 +431,26 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, | CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT; switch (depth) { + /* FIXME: support 8-bit grayscale and 8-bit RGB. */ case 32: + hidden_dac = CIRRUS_HIDDEN_DAC_888COLOR; sr_ext |= CIRRUS_SR_EXTENDED_MODE_32BPP; break; case 24: + hidden_dac = CIRRUS_HIDDEN_DAC_888COLOR; sr_ext |= CIRRUS_SR_EXTENDED_MODE_24BPP; break; case 16: + hidden_dac = CIRRUS_HIDDEN_DAC_16BPP; + sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP; + break; case 15: + hidden_dac = CIRRUS_HIDDEN_DAC_15BPP; sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP; break; } sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE); - write_hidden_dac (depth == 16); + write_hidden_dac (hidden_dac); } /* Fill mode info details. */ From 31e0ce4d105ac35b4f4d1103713bf66518b0fccf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 May 2010 21:18:40 +0200 Subject: [PATCH 203/503] Support index color in video_cirrus --- video/cirrus.c | 137 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 40 deletions(-) diff --git a/video/cirrus.c b/video/cirrus.c index 2e487311e..1e55770b4 100644 --- a/video/cirrus.c +++ b/video/cirrus.c @@ -40,12 +40,19 @@ static struct #define CIRRUS_APERTURE_SIZE 0x200000 -#define GR_INDEX 0x3ce -#define GR_DATA 0x3cf -#define CR_INDEX 0x3d4 -#define CR_DATA 0x3d5 -#define SR_INDEX 0x3c4 -#define SR_DATA 0x3c5 +enum + { + SR_INDEX = 0x3c4, + SR_DATA = 0x3c5, + CIRRUS_PIXEL_MASK = 0x3c6, + CIRRUS_PALLETTE_READ_INDEX = 0x3c7, + CIRRUS_PALLETTE_WRITE_INDEX = 0x3c8, + CIRRUS_PALLETTE_DATA = 0x3c9, + GR_INDEX = 0x3ce, + GR_DATA = 0x3cf, + CR_INDEX = 0x3d4, + CR_DATA = 0x3d5, + }; #define CIRRUS_MAX_WIDTH 0x800 #define CIRRUS_WIDTH_DIVISOR 8 @@ -117,12 +124,14 @@ enum #define CIRRUS_SR_MEMORY_MODE_NORMAL 0 #define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0 #define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01 -#define CIRRUS_SR_EXTENDED_MODE_24BPP 0x04 +#define CIRRUS_SR_EXTENDED_MODE_8BPP 0x00 #define CIRRUS_SR_EXTENDED_MODE_16BPP 0x06 +#define CIRRUS_SR_EXTENDED_MODE_24BPP 0x04 #define CIRRUS_SR_EXTENDED_MODE_32BPP 0x08 #define CIRRUS_HIDDEN_DAC_ENABLE_EXT 0x80 #define CIRRUS_HIDDEN_DAC_ENABLE_ALL 0x40 +#define CIRRUS_HIDDEN_DAC_8BPP 0 #define CIRRUS_HIDDEN_DAC_15BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 0) #define CIRRUS_HIDDEN_DAC_16BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ @@ -175,23 +184,43 @@ sr_read (grub_uint8_t addr) static void write_hidden_dac (grub_uint8_t data) { - grub_inb (0x3c8); - grub_inb (0x3c6); - grub_inb (0x3c6); - grub_inb (0x3c6); - grub_inb (0x3c6); - grub_outb (data, 0x3c6); + grub_inb (CIRRUS_PALLETTE_WRITE_INDEX); + grub_inb (CIRRUS_PIXEL_MASK); + grub_inb (CIRRUS_PIXEL_MASK); + grub_inb (CIRRUS_PIXEL_MASK); + grub_inb (CIRRUS_PIXEL_MASK); + grub_outb (data, CIRRUS_PIXEL_MASK); } static grub_uint8_t read_hidden_dac (void) { - grub_inb (0x3c8); - grub_inb (0x3c6); - grub_inb (0x3c6); - grub_inb (0x3c6); - grub_inb (0x3c6); - return grub_inb (0x3c6); + grub_inb (CIRRUS_PALLETTE_WRITE_INDEX); + grub_inb (CIRRUS_PIXEL_MASK); + grub_inb (CIRRUS_PIXEL_MASK); + grub_inb (CIRRUS_PIXEL_MASK); + grub_inb (CIRRUS_PIXEL_MASK); + return grub_inb (CIRRUS_PIXEL_MASK); +} + +static void +palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g, + grub_uint8_t *b) +{ + grub_outb (addr, CIRRUS_PALLETTE_READ_INDEX); + *r = grub_inb (CIRRUS_PALLETTE_DATA); + *g = grub_inb (CIRRUS_PALLETTE_DATA); + *b = grub_inb (CIRRUS_PALLETTE_DATA); +} + +static void +palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, + grub_uint8_t b) +{ + grub_outb (addr, CIRRUS_PALLETTE_READ_INDEX); + grub_outb (r, CIRRUS_PALLETTE_DATA); + grub_outb (g, CIRRUS_PALLETTE_DATA); + grub_outb (b, CIRRUS_PALLETTE_DATA); } struct saved_state @@ -202,6 +231,9 @@ struct saved_state grub_uint8_t hidden_dac; /* We need to preserve VGA font and VGA text. */ grub_uint8_t vram[32 * 4 * 256]; + grub_uint8_t r[256]; + grub_uint8_t g[256]; + grub_uint8_t b[256]; }; static struct saved_state initial_state; @@ -217,6 +249,9 @@ save_state (struct saved_state *st) st->sr[i] = sr_read (i); for (i = 0; i < ARRAY_SIZE (st->gr); i++) st->gr[i] = gr_read (i); + for (i = 0; i < 256; i++) + palette_read (i, st->r + i, st->g + i, st->b + i); + st->hidden_dac = read_hidden_dac (); sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram)); @@ -234,6 +269,9 @@ restore_state (struct saved_state *st) sr_write (st->sr[i], i); for (i = 0; i < ARRAY_SIZE (st->gr); i++) gr_write (st->gr[i], i); + for (i = 0; i < 256; i++) + palette_write (i, st->r[i], st->g[i], st->b[i]); + write_hidden_dac (st->hidden_dac); } @@ -289,9 +327,30 @@ doublebuf_pageflipping_set_page (int page) return GRUB_ERR_NONE; } +static grub_err_t +grub_video_cirrus_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + if (framebuffer.mode_info.mode_type == GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) + { + unsigned i; + if (start >= 0x100) + return GRUB_ERR_NONE; + if (start + count >= 0x100) + count = 0x100 - start; + + for (i = 0; i < count; i++) + palette_write (start + i, palette_data[i].r, palette_data[i].g, + palette_data[i].b); + } + + /* Then set color to emulated palette. */ + return grub_video_fb_set_palette (start, count, palette_data); +} + static grub_err_t grub_video_cirrus_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) + unsigned int mode_type, unsigned int mode_mask) { int depth; grub_err_t err; @@ -342,12 +401,17 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, return grub_error (GRUB_ERR_IO, "screen height must be at most %d", CIRRUS_MAX_HEIGHT); - if (depth == 0) + if (depth == 0 + && !grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, 0)) depth = 24; - if (depth != 32 && depth != 24 && depth != 16 && depth != 15) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "only 32, 24, 16 and 15-bit bpp are supported"); + if (depth == 0) + depth = 8; + + if (depth != 32 && depth != 24 && depth != 16 && depth != 15 && depth != 8) + return grub_error (GRUB_ERR_IO, "only 32, 24, 16, 15 and 8-bit bpp are" + " supported by cirrus video"); bytes_per_pixel = (depth + 7) / 8; pitch = width * bytes_per_pixel; @@ -448,6 +512,10 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, hidden_dac = CIRRUS_HIDDEN_DAC_15BPP; sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP; break; + case 8: + hidden_dac = CIRRUS_HIDDEN_DAC_8BPP; + sr_ext |= CIRRUS_SR_EXTENDED_MODE_8BPP; + break; } sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE); write_hidden_dac (hidden_dac); @@ -466,6 +534,9 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, switch (depth) { + case 8: + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + break; case 16: framebuffer.mode_info.red_mask_size = 5; framebuffer.mode_info.red_field_pos = 11; @@ -513,25 +584,11 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, /* Copy default palette to initialize emulated palette. */ - err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, - grub_video_fbstd_colors); + err = grub_video_cirrus_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); return err; } -static grub_err_t -grub_video_cirrus_set_palette (unsigned int start, unsigned int count, - struct grub_video_palette_data *palette_data) -{ - /* if (framebuffer.index_color_mode) */ - { - /* TODO: Implement setting indexed color mode palette to hardware. */ - } - - /* Then set color to emulated palette. */ - return grub_video_fb_set_palette (start, count, palette_data); -} - - static struct grub_video_adapter grub_video_cirrus_adapter = { .name = "Cirrus CLGD 5446 PCI Video Driver", From 9a3e298a7ed8f3c2d22dbbee7fc9ea8e67859b7b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 May 2010 22:20:19 +0200 Subject: [PATCH 204/503] Fix incorrect aperture size --- video/cirrus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/video/cirrus.c b/video/cirrus.c index 1e55770b4..457f38898 100644 --- a/video/cirrus.c +++ b/video/cirrus.c @@ -38,7 +38,7 @@ static struct grub_pci_device_t dev; } framebuffer; -#define CIRRUS_APERTURE_SIZE 0x200000 +#define CIRRUS_APERTURE_SIZE 0x1000000 enum { From 368e544ba6a5b3099fd48d4f4e08d0858e2e4f2b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 01:18:50 +0200 Subject: [PATCH 205/503] Add bochs video support --- conf/i386.rmk | 5 + include/grub/video.h | 3 +- video/bochs.c | 500 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 507 insertions(+), 1 deletion(-) create mode 100644 video/bochs.c diff --git a/conf/i386.rmk b/conf/i386.rmk index ce5d42f0f..5e1191c1e 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -20,6 +20,11 @@ video_cirrus_mod_SOURCES = video/cirrus.c video_cirrus_mod_CFLAGS = $(COMMON_CFLAGS) video_cirrus_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += video_bochs.mod +video_bochs_mod_SOURCES = video/bochs.c +video_bochs_mod_CFLAGS = $(COMMON_CFLAGS) +video_bochs_mod_LDFLAGS = $(COMMON_LDFLAGS) + pkglib_MODULES += relocator.mod relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S relocator_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/include/grub/video.h b/include/grub/video.h index 08ee54938..9ffc58d86 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -183,7 +183,8 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_EFI_GOP, GRUB_VIDEO_DRIVER_SM712, GRUB_VIDEO_DRIVER_VGA, - GRUB_VIDEO_DRIVER_CIRRUS + GRUB_VIDEO_DRIVER_CIRRUS, + GRUB_VIDEO_DRIVER_BOCHS } grub_video_driver_id_t; struct grub_video_adapter diff --git a/video/bochs.c b/video/bochs.c new file mode 100644 index 000000000..da63b2912 --- /dev/null +++ b/video/bochs.c @@ -0,0 +1,500 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct +{ + struct grub_video_mode_info mode_info; + + grub_uint8_t *ptr; + int mapped; + grub_uint32_t base; + grub_pci_device_t dev; +} framebuffer; + +#define BOCHS_APERTURE_SIZE 0x800000 +#define BOCHS_MAX_WIDTH 1600 +#define BOCHS_MAX_HEIGHT 1200 +#define BOCHS_WIDTH_ALIGN 8 + +enum + { + CIRRUS_SR_MEMORY_MODE = 4, + CIRRUS_SR_EXTENDED_MODE = 7, + CIRRUS_SR_MAX + }; +#define CIRRUS_SR_MEMORY_MODE_CHAIN4 8 + +enum + { + BOCHS_VBE_INDEX = 0x1ce, + BOCHS_VBE_DATA = 0x1cf, + SR_INDEX = 0x3c4, + SR_DATA = 0x3c5, + BOCHS_PALLETTE_READ_INDEX = 0x3c7, + BOCHS_PALLETTE_WRITE_INDEX = 0x3c8, + BOCHS_PALLETTE_DATA = 0x3c9, + GR_INDEX = 0x3ce, + GR_DATA = 0x3cf, + CR_INDEX = 0x3d4, + CR_DATA = 0x3d5, + }; + +enum + { + BOCHS_VBE_WIDTH = 1, + BOCHS_VBE_HEIGHT = 2, + BOCHS_VBE_BPP = 3, + BOCHS_VBE_ENABLE = 4, + BOCHS_VBE_Y_OFFSET = 9, + BOCHS_VBE_MAX + }; + +static void +vbe_write (grub_uint16_t val, grub_uint16_t addr) +{ + grub_outw (addr, BOCHS_VBE_INDEX); + grub_outw (val, BOCHS_VBE_DATA); +} + +static grub_uint16_t +vbe_read (grub_uint16_t addr) +{ + grub_outw (addr, BOCHS_VBE_INDEX); + return grub_inw (BOCHS_VBE_DATA); +} + +static void +gr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, GR_INDEX); + grub_outb (val, GR_DATA); +} + +static grub_uint8_t +gr_read (grub_uint8_t addr) +{ + grub_outb (addr, GR_INDEX); + return grub_inb (GR_DATA); +} + +static void +cr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, CR_INDEX); + grub_outb (val, CR_DATA); +} + +static grub_uint8_t +cr_read (grub_uint8_t addr) +{ + grub_outb (addr, CR_INDEX); + return grub_inb (CR_DATA); +} + +static void +palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g, + grub_uint8_t *b) +{ + grub_outb (addr, BOCHS_PALLETTE_READ_INDEX); + *r = grub_inb (BOCHS_PALLETTE_DATA); + *g = grub_inb (BOCHS_PALLETTE_DATA); + *b = grub_inb (BOCHS_PALLETTE_DATA); +} + +static void +palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, + grub_uint8_t b) +{ + grub_outb (addr, BOCHS_PALLETTE_READ_INDEX); + grub_outb (r, BOCHS_PALLETTE_DATA); + grub_outb (g, BOCHS_PALLETTE_DATA); + grub_outb (b, BOCHS_PALLETTE_DATA); +} +static void +sr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, SR_INDEX); + grub_outb (val, SR_DATA); +} + +static grub_uint8_t +sr_read (grub_uint8_t addr) +{ + grub_outb (addr, SR_INDEX); + return grub_inb (SR_DATA); +} + + +struct saved_state +{ + grub_uint8_t cr[256]; + grub_uint8_t gr[256]; + grub_uint8_t sr[256]; + grub_uint8_t r[256]; + grub_uint8_t g[256]; + grub_uint8_t b[256]; + grub_uint8_t vbe[BOCHS_VBE_MAX]; + int vbe_enable; + /* We need to preserve VGA font and VGA text. */ + grub_uint8_t vram[32 * 4 * 256]; +}; + +static struct saved_state initial_state; +static int state_saved = 0; + +static void +save_state (struct saved_state *st) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE (st->cr); i++) + st->cr[i] = cr_read (i); + for (i = 0; i < ARRAY_SIZE (st->gr); i++) + st->gr[i] = gr_read (i); + for (i = 0; i < ARRAY_SIZE (st->sr); i++) + st->sr[i] = sr_read (i); + grub_printf ("%d\n", st->cr[1]); + + for (i = 0; i < 256; i++) + palette_read (i, st->r + i, st->g + i, st->b + i); + + st->vbe_enable = vbe_read (BOCHS_VBE_ENABLE) & 1; + if (st->vbe_enable) + for (i = 0; i < ARRAY_SIZE (st->vbe); i++) + st->vbe[i] = vbe_read (i); + + sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram)); + sr_write (st->sr[CIRRUS_SR_MEMORY_MODE], CIRRUS_SR_MEMORY_MODE); +} + +static void +restore_state (struct saved_state *st) +{ + unsigned i; + + if (st->vbe_enable) + for (i = 0; i < ARRAY_SIZE (st->vbe); i++) + vbe_write (st->vbe[i], i); + else + vbe_write (0, BOCHS_VBE_ENABLE); + + cr_write (0, 0x11); + for (i = 0; i < ARRAY_SIZE (st->cr); i++) + cr_write (st->cr[i], i); + for (i = 0; i < ARRAY_SIZE (st->sr); i++) + sr_write (st->sr[i], i); + for (i = 0; i < ARRAY_SIZE (st->gr); i++) + gr_write (st->gr[i], i); + + for (i = 0; i < 256; i++) + palette_write (i, st->r[i], st->g[i], st->b[i]); + + sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram)); + sr_write (st->sr[CIRRUS_SR_MEMORY_MODE], CIRRUS_SR_MEMORY_MODE); +} + +static grub_err_t +grub_video_bochs_video_init (void) +{ + /* Reset frame buffer. */ + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + + return grub_video_fb_init (); +} + +static grub_err_t +grub_video_bochs_video_fini (void) +{ + if (framebuffer.mapped) + grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, + BOCHS_APERTURE_SIZE); + + if (state_saved) + { + restore_state (&initial_state); + state_saved = 0; + } + + return grub_video_fb_fini (); +} + +static grub_err_t +doublebuf_pageflipping_set_page (int page) +{ + int start = framebuffer.mode_info.height * page; + + vbe_write (start, BOCHS_VBE_Y_OFFSET); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_bochs_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + if (framebuffer.mode_info.mode_type == GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) + { + unsigned i; + if (start >= 0x100) + return GRUB_ERR_NONE; + if (start + count >= 0x100) + count = 0x100 - start; + + for (i = 0; i < count; i++) + palette_write (start + i, palette_data[i].r, palette_data[i].g, + palette_data[i].b); + } + + /* Then set color to emulated palette. */ + return grub_video_fb_set_palette (start, count, palette_data); +} + +static grub_err_t +grub_video_bochs_setup (unsigned int width, unsigned int height, + unsigned int mode_type, unsigned int mode_mask) +{ + int depth; + grub_err_t err; + int found = 0; + int pitch, bytes_per_pixel; + grub_size_t page_size; /* The size of a page in bytes. */ + + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x11111234) + return 0; + + found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + framebuffer.dev = dev; + + return 1; + } + + /* 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; + + if (width == 0 || height == 0) + { + width = 800; + height = 600; + } + + if (width > BOCHS_MAX_WIDTH) + return grub_error (GRUB_ERR_IO, "width must be at most", + BOCHS_MAX_WIDTH); + + if (height > BOCHS_MAX_HEIGHT) + return grub_error (GRUB_ERR_IO, "height must be at most", + BOCHS_MAX_HEIGHT); + + if (width & (BOCHS_WIDTH_ALIGN - 1)) + return grub_error (GRUB_ERR_IO, "width must be a multiple of %d", + BOCHS_WIDTH_ALIGN); + + if (depth == 0 + && !grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, 0)) + depth = 24; + + if (depth == 0) + depth = 8; + + if (depth != 32 && depth != 24 && depth != 16 && depth != 15 && depth != 8 + && depth != 4) + return grub_error (GRUB_ERR_IO, "only 32, 24, 16, 15 and 8-bpp are" + " supported by bochs video"); + + if (depth == 4) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "4-bpp isn't cupported"); + + bytes_per_pixel = (depth + 7) / 8; + if (depth == 4) + pitch = width / 2; + else + pitch = width * bytes_per_pixel; + + page_size = pitch * height; + + if (page_size > BOCHS_APERTURE_SIZE) + return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); + + grub_pci_iterate (find_card); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + + if (found && framebuffer.base == 0) + { + /* FIXME: change framebuffer base */ + return grub_error (GRUB_ERR_IO, "PCI BAR not set"); + } + + /* We can safely discard volatile attribute. */ + framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, + framebuffer.base, + BOCHS_APERTURE_SIZE); + framebuffer.mapped = 1; + + if (!state_saved) + { + save_state (&initial_state); + state_saved = 1; + } + + { + vbe_write (0, BOCHS_VBE_ENABLE); + + vbe_write (width, BOCHS_VBE_WIDTH); + vbe_write (height, BOCHS_VBE_HEIGHT); + vbe_write (depth, BOCHS_VBE_BPP); + + vbe_write (1, BOCHS_VBE_ENABLE); + doublebuf_pageflipping_set_page (0); + } + + /* Fill mode info details. */ + framebuffer.mode_info.width = width; + framebuffer.mode_info.height = height; + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; + framebuffer.mode_info.bpp = depth; + framebuffer.mode_info.bytes_per_pixel = bytes_per_pixel; + framebuffer.mode_info.pitch = pitch; + framebuffer.mode_info.number_of_colors = 256; + framebuffer.mode_info.reserved_mask_size = 0; + framebuffer.mode_info.reserved_field_pos = 0; + + switch (depth) + { + case 4: + case 8: + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + break; + case 16: + framebuffer.mode_info.red_mask_size = 5; + framebuffer.mode_info.red_field_pos = 11; + framebuffer.mode_info.green_mask_size = 6; + framebuffer.mode_info.green_field_pos = 5; + framebuffer.mode_info.blue_mask_size = 5; + framebuffer.mode_info.blue_field_pos = 0; + break; + + case 15: + framebuffer.mode_info.red_mask_size = 5; + framebuffer.mode_info.red_field_pos = 10; + framebuffer.mode_info.green_mask_size = 5; + framebuffer.mode_info.green_field_pos = 5; + framebuffer.mode_info.blue_mask_size = 5; + framebuffer.mode_info.blue_field_pos = 0; + break; + + case 32: + framebuffer.mode_info.reserved_mask_size = 8; + framebuffer.mode_info.reserved_field_pos = 24; + + case 24: + framebuffer.mode_info.red_mask_size = 8; + framebuffer.mode_info.red_field_pos = 16; + framebuffer.mode_info.green_mask_size = 8; + framebuffer.mode_info.green_field_pos = 8; + framebuffer.mode_info.blue_mask_size = 8; + framebuffer.mode_info.blue_field_pos = 0; + break; + } + + framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); + + if (BOCHS_APERTURE_SIZE >= 2 * page_size) + err = grub_video_fb_setup (mode_type, mode_mask, + &framebuffer.mode_info, + framebuffer.ptr, + doublebuf_pageflipping_set_page, + framebuffer.ptr + page_size); + else + err = grub_video_fb_setup (mode_type, mode_mask, + &framebuffer.mode_info, + framebuffer.ptr, 0, 0); + + + /* Copy default palette to initialize emulated palette. */ + err = grub_video_bochs_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + return err; +} + +static struct grub_video_adapter grub_video_bochs_adapter = + { + .name = "Bochs PCI Video Driver", + .id = GRUB_VIDEO_DRIVER_BOCHS, + + .init = grub_video_bochs_video_init, + .fini = grub_video_bochs_video_fini, + .setup = grub_video_bochs_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_fb_get_info_and_fini, + .set_palette = grub_video_bochs_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_fb_blit_bitmap, + .blit_render_target = grub_video_fb_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_fb_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_fb_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(video_bochs) +{ + grub_video_register (&grub_video_bochs_adapter); +} + +GRUB_MOD_FINI(video_bochs) +{ + grub_video_unregister (&grub_video_bochs_adapter); +} From 967828eb5afb0ea7981d39299debc1143960a9cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 02:25:37 +0200 Subject: [PATCH 206/503] macroify and share VGA registers --- include/grub/vga.h | 161 +++++++++++++++++++++++++++ term/i386/pc/vga_text.c | 23 +--- video/bochs.c | 111 +++---------------- video/cirrus.c | 239 +++++++++++----------------------------- video/i386/pc/vga.c | 63 ++--------- 5 files changed, 254 insertions(+), 343 deletions(-) create mode 100644 include/grub/vga.h diff --git a/include/grub/vga.h b/include/grub/vga.h new file mode 100644 index 000000000..d05ddd69b --- /dev/null +++ b/include/grub/vga.h @@ -0,0 +1,161 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_HEADER +#define GRUB_VGA_HEADER 1 + +enum + { + GRUB_VGA_IO_SR_INDEX = 0x3c4, + GRUB_VGA_IO_SR_DATA = 0x3c5, + GRUB_VGA_IO_PIXEL_MASK = 0x3c6, + GRUB_VGA_IO_PALLETTE_READ_INDEX = 0x3c7, + GRUB_VGA_IO_PALLETTE_WRITE_INDEX = 0x3c8, + GRUB_VGA_IO_PALLETTE_DATA = 0x3c9, + GRUB_VGA_IO_GR_INDEX = 0x3ce, + GRUB_VGA_IO_GR_DATA = 0x3cf, + GRUB_VGA_IO_CR_INDEX = 0x3d4, + GRUB_VGA_IO_CR_DATA = 0x3d5, + GRUB_VGA_IO_INPUT_STATUS1_REGISTER = 0x3da + }; + +#define GRUB_VGA_IO_INPUT_STATUS1_VERTR_BIT 0x08 + +enum + { + GRUB_VGA_CR_WIDTH = 0x01, + GRUB_VGA_CR_OVERFLOW = 0x07, + GRUB_VGA_CR_CELL_HEIGHT = 0x09, + GRUB_VGA_CR_CURSOR = 0x0a, + GRUB_VGA_CR_START_ADDR_HIGH_REGISTER = 0x0c, + GRUB_VGA_CR_START_ADDR_LOW_REGISTER = 0x0d, + GRUB_VGA_CR_CURSOR_ADDR_HIGH = 0x0e, + GRUB_VGA_CR_CURSOR_ADDR_LOW = 0x0f, + GRUB_VGA_CR_VSYNC_END = 0x11, + GRUB_VGA_CR_HEIGHT = 0x12, + GRUB_VGA_CR_PITCH = 0x13, + GRUB_VGA_CR_MODE = 0x17, + GRUB_VGA_CR_LINE_COMPARE = 0x18, + }; + +#define GRUB_VGA_CR_WIDTH_DIVISOR 8 +#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT 7 +#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK 0x02 +#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT 3 +#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK 0xc0 +#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT 4 +#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK 0x10 + +#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40 +#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3 + +#define GRUB_VGA_CR_CURSOR_DISABLE (1 << 5) + +#define GRUB_VGA_CR_PITCH_DIVISOR 8 + +#define GRUB_VGA_CR_MODE_TIMING_ENABLE 0x80 +#define GRUB_VGA_CR_MODE_BYTE_MODE 0x40 +#define GRUB_VGA_CR_MODE_NO_HERCULES 0x02 +#define GRUB_VGA_CR_MODE_NO_CGA 0x01 + +enum + { + GRUB_VGA_SR_MAP_MASK_REGISTER = 0x02, + GRUB_VGA_SR_MEMORY_MODE = 0x04, + }; + +#define GRUB_VGA_SR_MEMORY_MODE_CHAIN4 8 +#define GRUB_VGA_SR_MEMORY_MODE_NORMAL 0 + +enum + { + GRUB_VGA_GR_READ_MAP_REGISTER = 0x04, + GRUB_VGA_GR_MODE = 5, + GRUB_VGA_GR_GR6 = 6, + GRUB_VGA_GR_MAX + }; + +#define GRUB_VGA_GR_GR6_GRAPHICS_MODE 1 + +#define GRUB_VGA_GR_MODE_256_COLOR 0x40 +#define GRUB_VGA_GR_MODE_READ_MODE1 0x08 + +static inline void +grub_vga_gr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, GRUB_VGA_IO_GR_INDEX); + grub_outb (val, GRUB_VGA_IO_GR_DATA); +} + +static inline grub_uint8_t +grub_vga_gr_read (grub_uint8_t addr) +{ + grub_outb (addr, GRUB_VGA_IO_GR_INDEX); + return grub_inb (GRUB_VGA_IO_GR_DATA); +} + +static inline void +grub_vga_cr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, GRUB_VGA_IO_CR_INDEX); + grub_outb (val, GRUB_VGA_IO_CR_DATA); +} + +static inline grub_uint8_t +grub_vga_cr_read (grub_uint8_t addr) +{ + grub_outb (addr, GRUB_VGA_IO_CR_INDEX); + return grub_inb (GRUB_VGA_IO_CR_DATA); +} + +static inline void +grub_vga_sr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_outb (addr, GRUB_VGA_IO_SR_INDEX); + grub_outb (val, GRUB_VGA_IO_SR_DATA); +} + +static inline grub_uint8_t +grub_vga_sr_read (grub_uint8_t addr) +{ + grub_outb (addr, GRUB_VGA_IO_SR_INDEX); + return grub_inb (GRUB_VGA_IO_SR_DATA); +} + +static inline void +grub_vga_palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g, + grub_uint8_t *b) +{ + grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX); + *r = grub_inb (GRUB_VGA_IO_PALLETTE_DATA); + *g = grub_inb (GRUB_VGA_IO_PALLETTE_DATA); + *b = grub_inb (GRUB_VGA_IO_PALLETTE_DATA); +} + +static inline void +grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, + grub_uint8_t b) +{ + grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX); + grub_outb (r, GRUB_VGA_IO_PALLETTE_DATA); + grub_outb (g, GRUB_VGA_IO_PALLETTE_DATA); + grub_outb (b, GRUB_VGA_IO_PALLETTE_DATA); +} + + +#endif diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index f954cab43..8bc14cb61 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -20,6 +20,7 @@ #include #include #include +#include #define COLS 80 #define ROWS 25 @@ -28,15 +29,6 @@ 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) { @@ -53,10 +45,8 @@ 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); + grub_vga_cr_write (pos >> 8, GRUB_VGA_CR_CURSOR_ADDR_HIGH); + grub_vga_cr_write (pos & 0xFF, GRUB_VGA_CR_CURSOR_ADDR_LOW); } static void @@ -134,12 +124,11 @@ 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); + old = grub_vga_cr_read (GRUB_VGA_CR_CURSOR); if (on) - grub_outb (old & ~CRTC_CURSOR_DISABLE, CRTC_DATA_PORT); + grub_vga_cr_write (old & ~GRUB_VGA_CR_CURSOR_DISABLE, GRUB_VGA_CR_CURSOR); else - grub_outb (old | CRTC_CURSOR_DISABLE, CRTC_DATA_PORT); + grub_vga_cr_write (old | GRUB_VGA_CR_CURSOR_DISABLE, GRUB_VGA_CR_CURSOR); } static grub_err_t diff --git a/video/bochs.c b/video/bochs.c index da63b2912..cb04df9fc 100644 --- a/video/bochs.c +++ b/video/bochs.c @@ -26,6 +26,7 @@ #include #include #include +#include static struct { @@ -42,27 +43,10 @@ static struct #define BOCHS_MAX_HEIGHT 1200 #define BOCHS_WIDTH_ALIGN 8 -enum - { - CIRRUS_SR_MEMORY_MODE = 4, - CIRRUS_SR_EXTENDED_MODE = 7, - CIRRUS_SR_MAX - }; -#define CIRRUS_SR_MEMORY_MODE_CHAIN4 8 - enum { BOCHS_VBE_INDEX = 0x1ce, BOCHS_VBE_DATA = 0x1cf, - SR_INDEX = 0x3c4, - SR_DATA = 0x3c5, - BOCHS_PALLETTE_READ_INDEX = 0x3c7, - BOCHS_PALLETTE_WRITE_INDEX = 0x3c8, - BOCHS_PALLETTE_DATA = 0x3c9, - GR_INDEX = 0x3ce, - GR_DATA = 0x3cf, - CR_INDEX = 0x3d4, - CR_DATA = 0x3d5, }; enum @@ -89,68 +73,6 @@ vbe_read (grub_uint16_t addr) return grub_inw (BOCHS_VBE_DATA); } -static void -gr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, GR_INDEX); - grub_outb (val, GR_DATA); -} - -static grub_uint8_t -gr_read (grub_uint8_t addr) -{ - grub_outb (addr, GR_INDEX); - return grub_inb (GR_DATA); -} - -static void -cr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, CR_INDEX); - grub_outb (val, CR_DATA); -} - -static grub_uint8_t -cr_read (grub_uint8_t addr) -{ - grub_outb (addr, CR_INDEX); - return grub_inb (CR_DATA); -} - -static void -palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g, - grub_uint8_t *b) -{ - grub_outb (addr, BOCHS_PALLETTE_READ_INDEX); - *r = grub_inb (BOCHS_PALLETTE_DATA); - *g = grub_inb (BOCHS_PALLETTE_DATA); - *b = grub_inb (BOCHS_PALLETTE_DATA); -} - -static void -palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, - grub_uint8_t b) -{ - grub_outb (addr, BOCHS_PALLETTE_READ_INDEX); - grub_outb (r, BOCHS_PALLETTE_DATA); - grub_outb (g, BOCHS_PALLETTE_DATA); - grub_outb (b, BOCHS_PALLETTE_DATA); -} -static void -sr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, SR_INDEX); - grub_outb (val, SR_DATA); -} - -static grub_uint8_t -sr_read (grub_uint8_t addr) -{ - grub_outb (addr, SR_INDEX); - return grub_inb (SR_DATA); -} - - struct saved_state { grub_uint8_t cr[256]; @@ -174,24 +96,23 @@ save_state (struct saved_state *st) unsigned i; for (i = 0; i < ARRAY_SIZE (st->cr); i++) - st->cr[i] = cr_read (i); + st->cr[i] = grub_vga_cr_read (i); for (i = 0; i < ARRAY_SIZE (st->gr); i++) - st->gr[i] = gr_read (i); + st->gr[i] = grub_vga_gr_read (i); for (i = 0; i < ARRAY_SIZE (st->sr); i++) - st->sr[i] = sr_read (i); - grub_printf ("%d\n", st->cr[1]); + st->sr[i] = grub_vga_sr_read (i); for (i = 0; i < 256; i++) - palette_read (i, st->r + i, st->g + i, st->b + i); + grub_vga_palette_read (i, st->r + i, st->g + i, st->b + i); st->vbe_enable = vbe_read (BOCHS_VBE_ENABLE) & 1; if (st->vbe_enable) for (i = 0; i < ARRAY_SIZE (st->vbe); i++) st->vbe[i] = vbe_read (i); - sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram)); - sr_write (st->sr[CIRRUS_SR_MEMORY_MODE], CIRRUS_SR_MEMORY_MODE); + grub_vga_sr_write (st->sr[GRUB_VGA_SR_MEMORY_MODE], GRUB_VGA_SR_MEMORY_MODE); } static void @@ -205,20 +126,20 @@ restore_state (struct saved_state *st) else vbe_write (0, BOCHS_VBE_ENABLE); - cr_write (0, 0x11); + grub_vga_cr_write (0, 0x11); for (i = 0; i < ARRAY_SIZE (st->cr); i++) - cr_write (st->cr[i], i); + grub_vga_cr_write (st->cr[i], i); for (i = 0; i < ARRAY_SIZE (st->sr); i++) - sr_write (st->sr[i], i); + grub_vga_sr_write (st->sr[i], i); for (i = 0; i < ARRAY_SIZE (st->gr); i++) - gr_write (st->gr[i], i); + grub_vga_gr_write (st->gr[i], i); for (i = 0; i < 256; i++) - palette_write (i, st->r[i], st->g[i], st->b[i]); + grub_vga_palette_write (i, st->r[i], st->g[i], st->b[i]); - sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram)); - sr_write (st->sr[CIRRUS_SR_MEMORY_MODE], CIRRUS_SR_MEMORY_MODE); + grub_vga_sr_write (st->sr[GRUB_VGA_SR_MEMORY_MODE], GRUB_VGA_SR_MEMORY_MODE); } static grub_err_t @@ -268,8 +189,8 @@ grub_video_bochs_set_palette (unsigned int start, unsigned int count, count = 0x100 - start; for (i = 0; i < count; i++) - palette_write (start + i, palette_data[i].r, palette_data[i].g, - palette_data[i].b); + grub_vga_palette_write (start + i, palette_data[i].r, palette_data[i].g, + palette_data[i].b); } /* Then set color to emulated palette. */ diff --git a/video/cirrus.c b/video/cirrus.c index 457f38898..4a3d8243d 100644 --- a/video/cirrus.c +++ b/video/cirrus.c @@ -26,6 +26,7 @@ #include #include #include +#include static struct { @@ -40,69 +41,17 @@ static struct #define CIRRUS_APERTURE_SIZE 0x1000000 -enum - { - SR_INDEX = 0x3c4, - SR_DATA = 0x3c5, - CIRRUS_PIXEL_MASK = 0x3c6, - CIRRUS_PALLETTE_READ_INDEX = 0x3c7, - CIRRUS_PALLETTE_WRITE_INDEX = 0x3c8, - CIRRUS_PALLETTE_DATA = 0x3c9, - GR_INDEX = 0x3ce, - GR_DATA = 0x3cf, - CR_INDEX = 0x3d4, - CR_DATA = 0x3d5, - }; - #define CIRRUS_MAX_WIDTH 0x800 -#define CIRRUS_WIDTH_DIVISOR 8 #define CIRRUS_MAX_HEIGHT 0x800 -#define CIRRUS_MAX_PITCH (0x1ff * CIRRUS_WIDTH_DIVISOR) +#define CIRRUS_MAX_PITCH (0x1ff * GRUB_VGA_CR_PITCH_DIVISOR) enum { - CIRRUS_GR_MODE = 5, - CIRRUS_GR_GR6 = 6, - CIRRUS_GR_MAX - }; - -#define CIRRUS_GR_GR6_GRAPHICS_MODE 1 - -#define CIRRUS_GR_MODE_256_COLOR 0x40 -#define CIRRUS_GR_MODE_READ_MODE1 0x08 - -enum - { - CIRRUS_CR_WIDTH = 0x01, - CIRRUS_CR_OVERFLOW = 0x07, - CIRRUS_CR_CELL_HEIGHT = 0x09, - CIRRUS_CR_SCREEN_START_HIGH = 0xc, - CIRRUS_CR_SCREEN_START_LOW = 0xd, - CIRRUS_CR_VSYNC_END = 0x11, - CIRRUS_CR_HEIGHT = 0x12, - CIRRUS_CR_PITCH = 0x13, - CIRRUS_CR_MODE = 0x17, - CIRRUS_CR_LINE_COMPARE = 0x18, CIRRUS_CR_EXTENDED_DISPLAY = 0x1b, CIRRUS_CR_EXTENDED_OVERLAY = 0x1d, CIRRUS_CR_MAX }; -#define CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40 -#define CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3 - -#define CIRRUS_CR_OVERFLOW_HEIGHT1_SHIFT 7 -#define CIRRUS_CR_OVERFLOW_HEIGHT1_MASK 0x02 -#define CIRRUS_CR_OVERFLOW_HEIGHT2_SHIFT 3 -#define CIRRUS_CR_OVERFLOW_HEIGHT2_MASK 0xc0 -#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_SHIFT 4 -#define CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK 0x10 - -#define CIRRUS_CR_MODE_TIMING_ENABLE 0x80 -#define CIRRUS_CR_MODE_BYTE_MODE 0x40 -#define CIRRUS_CR_MODE_NO_HERCULES 0x02 -#define CIRRUS_CR_MODE_NO_CGA 0x01 - #define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK 0x10 #define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT 4 #define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 0x1 @@ -113,15 +62,12 @@ enum #define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK 0x80 #define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT 12 - enum { - CIRRUS_SR_MEMORY_MODE = 4, CIRRUS_SR_EXTENDED_MODE = 7, CIRRUS_SR_MAX }; -#define CIRRUS_SR_MEMORY_MODE_CHAIN4 8 -#define CIRRUS_SR_MEMORY_MODE_NORMAL 0 + #define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0 #define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01 #define CIRRUS_SR_EXTENDED_MODE_8BPP 0x00 @@ -139,94 +85,32 @@ enum #define CIRRUS_HIDDEN_DAC_888COLOR (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 5) -static void -gr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, GR_INDEX); - grub_outb (val, GR_DATA); -} - -static grub_uint8_t -gr_read (grub_uint8_t addr) -{ - grub_outb (addr, GR_INDEX); - return grub_inb (GR_DATA); -} - -static void -cr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, CR_INDEX); - grub_outb (val, CR_DATA); -} - -static grub_uint8_t -cr_read (grub_uint8_t addr) -{ - grub_outb (addr, CR_INDEX); - return grub_inb (CR_DATA); -} - -static void -sr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, SR_INDEX); - grub_outb (val, SR_DATA); -} - -static grub_uint8_t -sr_read (grub_uint8_t addr) -{ - grub_outb (addr, SR_INDEX); - return grub_inb (SR_DATA); -} - static void write_hidden_dac (grub_uint8_t data) { - grub_inb (CIRRUS_PALLETTE_WRITE_INDEX); - grub_inb (CIRRUS_PIXEL_MASK); - grub_inb (CIRRUS_PIXEL_MASK); - grub_inb (CIRRUS_PIXEL_MASK); - grub_inb (CIRRUS_PIXEL_MASK); - grub_outb (data, CIRRUS_PIXEL_MASK); + grub_inb (GRUB_VGA_IO_PALLETTE_WRITE_INDEX); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + grub_outb (data, GRUB_VGA_IO_PIXEL_MASK); } static grub_uint8_t read_hidden_dac (void) { - grub_inb (CIRRUS_PALLETTE_WRITE_INDEX); - grub_inb (CIRRUS_PIXEL_MASK); - grub_inb (CIRRUS_PIXEL_MASK); - grub_inb (CIRRUS_PIXEL_MASK); - grub_inb (CIRRUS_PIXEL_MASK); - return grub_inb (CIRRUS_PIXEL_MASK); -} - -static void -palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g, - grub_uint8_t *b) -{ - grub_outb (addr, CIRRUS_PALLETTE_READ_INDEX); - *r = grub_inb (CIRRUS_PALLETTE_DATA); - *g = grub_inb (CIRRUS_PALLETTE_DATA); - *b = grub_inb (CIRRUS_PALLETTE_DATA); -} - -static void -palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, - grub_uint8_t b) -{ - grub_outb (addr, CIRRUS_PALLETTE_READ_INDEX); - grub_outb (r, CIRRUS_PALLETTE_DATA); - grub_outb (g, CIRRUS_PALLETTE_DATA); - grub_outb (b, CIRRUS_PALLETTE_DATA); + grub_inb (GRUB_VGA_IO_PALLETTE_WRITE_INDEX); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + grub_inb (GRUB_VGA_IO_PIXEL_MASK); + return grub_inb (GRUB_VGA_IO_PIXEL_MASK); } struct saved_state { grub_uint8_t cr[CIRRUS_CR_MAX]; - grub_uint8_t gr[CIRRUS_GR_MAX]; + grub_uint8_t gr[GRUB_VGA_GR_MAX]; grub_uint8_t sr[CIRRUS_SR_MAX]; grub_uint8_t hidden_dac; /* We need to preserve VGA font and VGA text. */ @@ -244,16 +128,16 @@ save_state (struct saved_state *st) { unsigned i; for (i = 0; i < ARRAY_SIZE (st->cr); i++) - st->cr[i] = cr_read (i); + st->cr[i] = grub_vga_cr_read (i); for (i = 0; i < ARRAY_SIZE (st->sr); i++) - st->sr[i] = sr_read (i); + st->sr[i] = grub_vga_sr_read (i); for (i = 0; i < ARRAY_SIZE (st->gr); i++) - st->gr[i] = gr_read (i); + st->gr[i] = grub_vga_gr_read (i); for (i = 0; i < 256; i++) - palette_read (i, st->r + i, st->g + i, st->b + i); + grub_vga_palette_read (i, st->r + i, st->g + i, st->b + i); st->hidden_dac = read_hidden_dac (); - sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram)); } @@ -261,16 +145,16 @@ static void restore_state (struct saved_state *st) { unsigned i; - sr_write (CIRRUS_SR_MEMORY_MODE_CHAIN4, CIRRUS_SR_MEMORY_MODE); + grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram)); for (i = 0; i < ARRAY_SIZE (st->cr); i++) - cr_write (st->cr[i], i); + grub_vga_cr_write (st->cr[i], i); for (i = 0; i < ARRAY_SIZE (st->sr); i++) - sr_write (st->sr[i], i); + grub_vga_sr_write (st->sr[i], i); for (i = 0; i < ARRAY_SIZE (st->gr); i++) - gr_write (st->gr[i], i); + grub_vga_gr_write (st->gr[i], i); for (i = 0; i < 256; i++) - palette_write (i, st->r[i], st->g[i], st->b[i]); + grub_vga_palette_write (i, st->r[i], st->g[i], st->b[i]); write_hidden_dac (st->hidden_dac); } @@ -306,23 +190,24 @@ doublebuf_pageflipping_set_page (int page) int start = framebuffer.page_size * page / 4; grub_uint8_t cr_ext, cr_overlay; - cr_write (start & 0xff, CIRRUS_CR_SCREEN_START_LOW); - cr_write ((start & 0xff00) >> 8, CIRRUS_CR_SCREEN_START_HIGH); + grub_vga_cr_write (start & 0xff, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); + grub_vga_cr_write ((start & 0xff00) >> 8, + GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); - cr_ext = cr_read (CIRRUS_CR_EXTENDED_DISPLAY); + cr_ext = grub_vga_cr_read (CIRRUS_CR_EXTENDED_DISPLAY); cr_ext &= ~(CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 | CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2); cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT1) & CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1); cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT2) & CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2); - cr_write (cr_ext, CIRRUS_CR_EXTENDED_DISPLAY); + grub_vga_cr_write (cr_ext, CIRRUS_CR_EXTENDED_DISPLAY); - cr_overlay = cr_read (CIRRUS_CR_EXTENDED_OVERLAY); + cr_overlay = grub_vga_cr_read (CIRRUS_CR_EXTENDED_OVERLAY); cr_overlay &= ~(CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK); cr_overlay |= ((start >> CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT) & CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK); - cr_write (cr_overlay, CIRRUS_CR_EXTENDED_OVERLAY); + grub_vga_cr_write (cr_overlay, CIRRUS_CR_EXTENDED_OVERLAY); return GRUB_ERR_NONE; } @@ -340,8 +225,8 @@ grub_video_cirrus_set_palette (unsigned int start, unsigned int count, count = 0x100 - start; for (i = 0; i < count; i++) - palette_write (start + i, palette_data[i].r, palette_data[i].g, - palette_data[i].b); + grub_vga_palette_write (start + i, palette_data[i].r, palette_data[i].g, + palette_data[i].b); } /* Then set color to emulated palette. */ @@ -388,10 +273,10 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, height = 600; } - if (width & (CIRRUS_WIDTH_DIVISOR - 1)) + if (width & (GRUB_VGA_CR_WIDTH_DIVISOR - 1)) return grub_error (GRUB_ERR_IO, "screen width must be a multiple of %d", - CIRRUS_WIDTH_DIVISOR); + GRUB_VGA_CR_WIDTH_DIVISOR); if (width > CIRRUS_MAX_WIDTH) return grub_error (GRUB_ERR_IO, @@ -452,42 +337,44 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, int pitch_reg, overflow_reg = 0, line_compare = 0x3ff; grub_uint8_t sr_ext = 0, hidden_dac = 0; - pitch_reg = pitch / CIRRUS_WIDTH_DIVISOR; + pitch_reg = pitch / GRUB_VGA_CR_PITCH_DIVISOR; - gr_write (CIRRUS_GR_MODE_256_COLOR | CIRRUS_GR_MODE_READ_MODE1, - CIRRUS_GR_MODE); - gr_write (CIRRUS_GR_GR6_GRAPHICS_MODE, CIRRUS_GR_GR6); + grub_vga_gr_write (GRUB_VGA_GR_MODE_256_COLOR | GRUB_VGA_GR_MODE_READ_MODE1, + GRUB_VGA_GR_MODE); + grub_vga_gr_write (GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6); - sr_write (CIRRUS_SR_MEMORY_MODE_NORMAL, CIRRUS_SR_MEMORY_MODE); + grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE); /* Disable CR0-7 write protection. */ - cr_write (0, CIRRUS_CR_VSYNC_END); + grub_vga_cr_write (0, GRUB_VGA_CR_VSYNC_END); - cr_write (width / CIRRUS_WIDTH_DIVISOR - 1, CIRRUS_CR_WIDTH); - cr_write ((height - 1) & 0xff, CIRRUS_CR_HEIGHT); - overflow_reg |= (((height - 1) >> CIRRUS_CR_OVERFLOW_HEIGHT1_SHIFT) & - CIRRUS_CR_OVERFLOW_HEIGHT1_MASK) - | (((height - 1) >> CIRRUS_CR_OVERFLOW_HEIGHT2_SHIFT) & - CIRRUS_CR_OVERFLOW_HEIGHT2_MASK); + grub_vga_cr_write (width / GRUB_VGA_CR_WIDTH_DIVISOR - 1, + GRUB_VGA_CR_WIDTH); + grub_vga_cr_write ((height - 1) & 0xff, GRUB_VGA_CR_HEIGHT); + overflow_reg |= (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT) & + GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK) + | (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT) & + GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK); - cr_write (pitch_reg & 0xff, CIRRUS_CR_PITCH); + grub_vga_cr_write (pitch_reg & 0xff, GRUB_VGA_CR_PITCH); - cr_write (line_compare & 0xff, CIRRUS_CR_LINE_COMPARE); - overflow_reg |= (line_compare >> CIRRUS_CR_OVERFLOW_LINE_COMPARE_SHIFT) - & CIRRUS_CR_OVERFLOW_LINE_COMPARE_MASK; + grub_vga_cr_write (line_compare & 0xff, GRUB_VGA_CR_LINE_COMPARE); + overflow_reg |= (line_compare >> GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT) + & GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK; - cr_write (overflow_reg, CIRRUS_CR_OVERFLOW); + grub_vga_cr_write (overflow_reg, GRUB_VGA_CR_OVERFLOW); - cr_write ((pitch_reg >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT) + grub_vga_cr_write ((pitch_reg >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT) & CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK, CIRRUS_CR_EXTENDED_DISPLAY); - cr_write ((line_compare >> CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT) - & CIRRUS_CR_CELL_HEIGHT_LINE_COMPARE_MASK, CIRRUS_CR_CELL_HEIGHT); + grub_vga_cr_write ((line_compare >> GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT) + & GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK, GRUB_VGA_CR_CELL_HEIGHT); - cr_write (CIRRUS_CR_MODE_TIMING_ENABLE | CIRRUS_CR_MODE_BYTE_MODE - | CIRRUS_CR_MODE_NO_HERCULES | CIRRUS_CR_MODE_NO_CGA, - CIRRUS_CR_MODE); + grub_vga_cr_write (GRUB_VGA_CR_MODE_TIMING_ENABLE + | GRUB_VGA_CR_MODE_BYTE_MODE + | GRUB_VGA_CR_MODE_NO_HERCULES | GRUB_VGA_CR_MODE_NO_CGA, + GRUB_VGA_CR_MODE); doublebuf_pageflipping_set_page (0); @@ -517,7 +404,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, sr_ext |= CIRRUS_SR_EXTENDED_MODE_8BPP; break; } - sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE); + grub_vga_sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE); write_hidden_dac (hidden_dac); } diff --git a/video/i386/pc/vga.c b/video/i386/pc/vga.c index 222a71272..7e923bddd 100644 --- a/video/i386/pc/vga.c +++ b/video/i386/pc/vga.c @@ -27,6 +27,7 @@ #include #include #include +#include #define VGA_WIDTH 640 #define VGA_HEIGHT 350 @@ -45,58 +46,26 @@ static struct int back_page; } framebuffer; -#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)); + while (! (grub_inb (GRUB_VGA_IO_INPUT_STATUS1_REGISTER) + & GRUB_VGA_IO_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; + return grub_vga_sr_read (GRUB_VGA_SR_MAP_MASK_REGISTER); } /* 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); + grub_vga_sr_write (mask, GRUB_VGA_SR_MAP_MASK_REGISTER); } #if 0 @@ -104,14 +73,7 @@ set_map_mask (unsigned char mask) 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); + grub_vga_gr_write (map, GRUB_VGA_GR_READ_MAP_REGISTER); } #endif @@ -119,17 +81,8 @@ set_read_map (unsigned char map) 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); + grub_vga_cr_write (start & 0xFF, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); + grub_vga_cr_write (start >> 8, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); } static int setup = 0; From 7e70395f9c8cf179832a9d5070d108fdfe3f82ef Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 21:35:39 +0200 Subject: [PATCH 207/503] Cherrypick bugfixes and coreboot+qemu support from expermental --- util/grub-mkrescue.in | 147 ++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 70 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 993ffe0cb..4e105f125 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -30,10 +30,13 @@ target_cpu=@target_cpu@ native_platform=@platform@ pkglib_DATA="@pkglib_DATA@" -multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-multiboot -pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc +multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot +coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot +qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu +pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi +rom_directory= # Usage: usage # Print the usage. @@ -44,8 +47,9 @@ Make GRUB rescue image. -h, --help print this message and exit -v, --version print the version information and exit - --modules=MODULES pre-load specified modules MODULES --output=FILE save output in FILE [required] + --modules=MODULES pre-load specified modules MODULES + --rom-directory=DIR save rom images in DIR [optional] $0 generates a bootable rescue image with specified source files or directories. @@ -66,6 +70,8 @@ for option in "$@"; do modules=`echo "$option" | sed 's/--modules=//'` ;; --output=*) output_image=`echo "$option" | sed 's/--output=//'` ;; + --rom-directory=*) + rom_directory=`echo "$option" | sed 's/--rom-directory=//'` ;; # Intentionally undocumented --override-directory=*) override_dir=`echo "${option}/" | sed 's/--override-directory=//'` @@ -103,15 +109,15 @@ process_input_dir () { input_dir="$1" platform="$2" - mkdir -p ${iso9660_dir}/boot/grub/${target_cpu}-${platform} + mkdir -p ${iso9660_dir}/boot/grub/${platform} for file in ${input_dir}/*.mod; do if test -f "$file"; then - cp -f "$file" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ + cp -f "$file" ${iso9660_dir}/boot/grub/${platform}/ fi done for file in ${pkglib_DATA}; do if test -f "${input_dir}/${file}"; then - cp -f "${input_dir}/${file}" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ + cp -f "${input_dir}/${file}" ${iso9660_dir}/boot/grub/${platform}/ fi done @@ -123,28 +129,71 @@ process_input_dir () done } +make_image () +{ + source_directory="$1" + platform=$2 + if ! test -e "${source_directory}"; then + return; + fi + + echo "Enabling $2 support ..." + + memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` + memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + mkdir -p ${memdisk_dir}/boot/grub + + modules="$(cat ${source_directory}/partmap.lst) ${modules}" + cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg +search --fs-uuid --set ${iso_uuid} +set prefix=(\${root})/boot/grub/${platform} +source \$prefix/grub.cfg +EOF + (for i in ${modules} ; do + echo "insmod $i" + done ; \ + echo "source /boot/grub/grub.cfg") \ + > ${iso9660_dir}/boot/grub/${platform}/grub.cfg + + tar -C ${memdisk_dir} -cf ${memdisk_img} boot + rm -rf ${memdisk_dir} + grub-mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ + search iso9660 configfile normal memdisk tar $4 + rm -rf ${memdisk_img} +} + if [ "${override_dir}" = "" ] ; then if test -e "${multiboot_dir}" ; then - process_input_dir ${multiboot_dir} multiboot + process_input_dir ${multiboot_dir} i386-multiboot + fi + if test -e "${coreboot_dir}" ; then + process_input_dir ${coreboot_dir} i386-coreboot + fi + if test -e "${qemu_dir}" ; then + process_input_dir ${qemu_dir} i386-qemu fi if test -e "${pc_dir}" ; then - process_input_dir ${pc_dir} pc + process_input_dir ${pc_dir} i386-pc fi if test -e "${efi32_dir}" ; then - process_input_dir ${efi32_dir} efi32 + process_input_dir ${efi32_dir} i386-efi fi if test -e "${efi64_dir}" ; then - process_input_dir ${efi64_dir} efi64 + process_input_dir ${efi64_dir} x86_64-efi fi else - process_input_dir ${override_dir} ${native_platform} + process_input_dir ${override_dir} ${target_cpu}-${native_platform} multiboot_dir= pc_dir= efi32_dir= efi64_dir= + coreboot_dir= + qemu_dir= case "${target_cpu}-${native_platform}" in - i386-pc) pc_dir=${override_dir} ;; i386-multiboot) multiboot_dir=${override_dir} ;; + i386-coreboot) coreboot_dir=${override_dir} ;; + i386-qemu) qemu_dir=${override_dir} ;; + i386-pc) pc_dir=${override_dir} ;; i386-efi) efi32_dir=${override_dir} ;; x86_64-efi) efi64_dir=${override_dir} ;; esac @@ -154,33 +203,6 @@ fi iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" -# build coreboot multiboot.img -if test -e "${multiboot_dir}" ; then - echo "Enabling multiboot support ..." - memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` - memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` - mkdir -p ${memdisk_dir}/boot/grub - - modules="$(cat ${multiboot_dir}/partmap.lst) ${modules}" - cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg -search --fs-uuid --set ${iso_uuid} -set prefix=(\${root})/boot/grub/${target_cpu}-multiboot -source \$prefix/grub.cfg -EOF - (for i in ${modules} ; do - echo "insmod $i" - done ; \ - echo "source /boot/grub/grub.cfg") \ - > ${iso9660_dir}/boot/grub/i386-multiboot/grub.cfg - - tar -C ${memdisk_dir} -cf ${memdisk_img} boot - rm -rf ${memdisk_dir} - grub-mkimage -O i386-coreboot -d ${multiboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ - memdisk tar search iso9660 configfile sh \ - ata at_keyboard - rm -f ${memdisk_img} -fi - # build BIOS core.img if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." @@ -205,47 +227,32 @@ if test -e "${pc_dir}" ; then --embedded-boot ${embed_img}" fi +# build multiboot core.img +make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "ata at_keyboard" + if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then efi_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p "${efi_dir}/efi/boot" -else - efi_dir= -fi -# build bootx64.efi -if test -e "${efi64_dir}" ; then - echo "Enabling EFI64 support ..." - memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` - memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` - mkdir -p ${memdisk_dir}/boot/grub + # build bootx64.efi + make_image "${efi64_dir}" x86_64-efi "${efi_dir}"/efi/boot/bootx64.efi "" + # build bootia32.efi + make_image "${efi32_dir}" i386-efi "${efi_dir}"/efi/boot/bootia32.efi "" - cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg -search --fs-uuid --set ${iso_uuid} -set prefix=(\${root})/boot/grub/${target_cpu}-efi -source \$prefix/grub.cfg -EOF - - tar -C ${memdisk_dir} -cf ${memdisk_img} boot - rm -rf ${memdisk_dir} - - grub-mkimage -O x86_64-efi -d "${efi64_dir}" -m "${memdisk_img}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix='(memdisk)/boot/grub' \ - search iso9660 configfile sh memdisk tar - rm -f ${memdisk_img} - - modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}" - (for i in ${modules} ; do - echo "insmod $i" - done ; \ - echo "source /boot/grub/grub.cfg") \ - > "${iso9660_dir}"/boot/grub/x86_64-efi/grub.cfg -fi - -if test x"${efi_dir}" != x; then mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" fi +make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/qemu.img" "ata at_keyboard" +if [ -e "${iso9660_dir}/boot/qemu.img" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/qemu.img" "${rom_directory}/qemu.img" +fi +make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/coreboot.elf" "ata at_keyboard" +if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/coreboot.elf" "${rom_directory}/coreboot.elf" +fi + # build iso image xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} From 8b26d1d30b1a984ac320c37ea7e8c8986ea9ff16 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 22:23:22 +0200 Subject: [PATCH 208/503] add missing sh.mod --- util/grub-mkrescue.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4e105f125..5f35f084a 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -158,7 +158,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} grub-mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ - search iso9660 configfile normal memdisk tar $4 + search iso9660 configfile normal sh memdisk tar $4 rm -rf ${memdisk_img} } From 6198f888c9a9a0f37aac413e16a50198b5843974 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 22:28:51 +0200 Subject: [PATCH 209/503] Revert spurious change in Makefile.in --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 3df8b1b72..26a494518 100644 --- a/Makefile.in +++ b/Makefile.in @@ -287,7 +287,7 @@ build_env.mk: Makefile echo "TARGET_CC=$(TARGET_CC)" ; \ echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \ echo "TARGET_ASFLAGS=$(TARGET_ASFLAGS)" ; \ - echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(libdir) -I$(includedir)" ; \ + echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir) -I$(includedir)" ; \ echo "STRIP=$(STRIP)" ; \ echo "OBJCONV=$(OBJCONV)" ; \ echo "TARGET_MODULE_FORMAT=$(TARGET_MODULE_FORMAT)" ; \ From 1d3293d67dabf99bed6dc4e8d22389614821d64c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 23:33:03 +0200 Subject: [PATCH 210/503] Remove grub-mkisofs. * conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs. (grub_mkisofs_SOURCES): Removed. (grub_mkisofs_CFLAGS): Removed. * util/mkisofs/defaults.h: Removed. * util/mkisofs/eltorito.c: Likewise. * util/mkisofs/exclude.h: Likewise. * util/mkisofs/hash.c: Likewise. * util/mkisofs/include/: Likewise. * util/mkisofs/include/fctldefs.h: Likewise. * util/mkisofs/include/mconfig.h: Likewise. * util/mkisofs/include/prototyp.h: Likewise. * util/mkisofs/include/statdefs.h: Likewise. * util/mkisofs/iso9660.h: Likewise. * util/mkisofs/joliet.c: Likewise. * util/mkisofs/match.c: Likewise. * util/mkisofs/match.h: Likewise. * util/mkisofs/mkisofs.c: Likewise. * util/mkisofs/mkisofs.h: Likewise. * util/mkisofs/msdos_partition.h: Likewise. * util/mkisofs/multi.c: Likewise. * util/mkisofs/name.c: Likewise. * util/mkisofs/rock.c: Likewise. * util/mkisofs/tree.c: Likewise. * util/mkisofs/write.c: Likewise. --- ChangeLog | 29 + conf/common.rmk | 14 - util/mkisofs/defaults.h | 20 - util/mkisofs/eltorito.c | 343 ------ util/mkisofs/exclude.h | 10 - util/mkisofs/hash.c | 225 ---- util/mkisofs/include/fctldefs.h | 57 - util/mkisofs/include/mconfig.h | 253 ----- util/mkisofs/include/prototyp.h | 74 -- util/mkisofs/include/statdefs.h | 139 --- util/mkisofs/iso9660.h | 174 --- util/mkisofs/joliet.c | 1023 ----------------- util/mkisofs/match.c | 76 -- util/mkisofs/match.h | 29 - util/mkisofs/mkisofs.c | 1422 ----------------------- util/mkisofs/mkisofs.h | 530 --------- util/mkisofs/msdos_partition.h | 75 -- util/mkisofs/multi.c | 1201 -------------------- util/mkisofs/name.c | 394 ------- util/mkisofs/rock.c | 597 ---------- util/mkisofs/tree.c | 1865 ------------------------------- util/mkisofs/write.c | 1483 ------------------------ 22 files changed, 29 insertions(+), 10004 deletions(-) delete mode 100644 util/mkisofs/defaults.h delete mode 100644 util/mkisofs/eltorito.c delete mode 100644 util/mkisofs/exclude.h delete mode 100644 util/mkisofs/hash.c delete mode 100644 util/mkisofs/include/fctldefs.h delete mode 100644 util/mkisofs/include/mconfig.h delete mode 100644 util/mkisofs/include/prototyp.h delete mode 100644 util/mkisofs/include/statdefs.h delete mode 100644 util/mkisofs/iso9660.h delete mode 100644 util/mkisofs/joliet.c delete mode 100644 util/mkisofs/match.c delete mode 100644 util/mkisofs/match.h delete mode 100644 util/mkisofs/mkisofs.c delete mode 100644 util/mkisofs/mkisofs.h delete mode 100644 util/mkisofs/msdos_partition.h delete mode 100644 util/mkisofs/multi.c delete mode 100644 util/mkisofs/name.c delete mode 100644 util/mkisofs/rock.c delete mode 100644 util/mkisofs/tree.c delete mode 100644 util/mkisofs/write.c diff --git a/ChangeLog b/ChangeLog index 5f3410ea1..8258400c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2010-05-17 Vladimir Serbinenko + + Remove grub-mkisofs. + + * conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs. + (grub_mkisofs_SOURCES): Removed. + (grub_mkisofs_CFLAGS): Removed. + * util/mkisofs/defaults.h: Removed. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/exclude.h: Likewise. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/include/: Likewise. + * util/mkisofs/include/fctldefs.h: Likewise. + * util/mkisofs/include/mconfig.h: Likewise. + * util/mkisofs/include/prototyp.h: Likewise. + * util/mkisofs/include/statdefs.h: Likewise. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/match.c: Likewise. + * util/mkisofs/match.h: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/msdos_partition.h: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + 2010-05-17 Vladimir Serbinenko Unify grub-mkimage accross platforms. diff --git a/conf/common.rmk b/conf/common.rmk index 00efa78fb..4186c61b2 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -43,20 +43,6 @@ ifeq ($(enable_grub_fstest), yes) bin_UTILITIES += grub-fstest endif -bin_UTILITIES += grub-mkisofs -grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \ - util/mkisofs/hash.c util/mkisofs/joliet.c \ - util/mkisofs/match.c util/mkisofs/mkisofs.c \ - util/mkisofs/multi.c util/mkisofs/name.c \ - util/mkisofs/rock.c util/mkisofs/tree.c \ - util/mkisofs/write.c \ - \ - gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c \ - gnulib/error.c gnulib/progname.c -grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ - -I$(srcdir)/util/mkisofs/include \ - -Wno-all -Werror $(GNULIB_UTIL_CFLAGS) - # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ diff --git a/util/mkisofs/defaults.h b/util/mkisofs/defaults.h deleted file mode 100644 index 2ce9e8d6b..000000000 --- a/util/mkisofs/defaults.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Header file defaults.h - assorted default values for character strings in - * the volume descriptor. - * - * $Id: defaults.h,v 1.8 1999/03/02 03:41:25 eric Exp $ - */ - -#define PREPARER_DEFAULT NULL -#define PUBLISHER_DEFAULT NULL -#ifndef APPID_DEFAULT -#define APPID_DEFAULT PACKAGE_NAME " ISO 9660 filesystem builder" -#endif -#define COPYRIGHT_DEFAULT NULL -#define BIBLIO_DEFAULT NULL -#define ABSTRACT_DEFAULT NULL -#define VOLSET_ID_DEFAULT NULL -#define VOLUME_ID_DEFAULT "CDROM" -#define BOOT_CATALOG_DEFAULT "boot.catalog" -#define BOOT_IMAGE_DEFAULT NULL -#define SYSTEM_ID_DEFAULT "GNU" diff --git a/util/mkisofs/eltorito.c b/util/mkisofs/eltorito.c deleted file mode 100644 index 1d2a715e0..000000000 --- a/util/mkisofs/eltorito.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Program eltorito.c - Handle El Torito specific extensions to iso9660. - * - - Written by Michael Fulbright (1996). - - Copyright 1996 RedHat Software, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - Boot Info Table generation based on code from genisoimage.c - (from cdrkit 1.1.9), which was originally licensed under GPLv2+. - - 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, see . - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "mkisofs.h" -#include "iso9660.h" - -/* used by Win32 for opening binary file - not used by Unix */ -#ifndef O_BINARY -#define O_BINARY 0 -#endif /* O_BINARY */ - -#undef MIN -#define MIN(a, b) (((a) < (b))? (a): (b)) - -static struct eltorito_validation_entry valid_desc; -static struct eltorito_defaultboot_entry default_desc; -static struct eltorito_boot_descriptor gboot_desc; - -static int tvd_write __PR((FILE * outfile)); - -/* - * Check for presence of boot catalog. If it does not exist then make it - */ -void FDECL1(init_boot_catalog, const char *, path) -{ - FILE *bcat; - char * bootpath; /* filename of boot catalog */ - char * buf; - struct stat statbuf; - - bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2); - strcpy(bootpath, path); - if (bootpath[strlen(bootpath)-1] != '/') - { - strcat(bootpath,"/"); - } - - strcat(bootpath, boot_catalog); - - /* - * check for the file existing - */ -#ifdef DEBUG_TORITO - fprintf(stderr,"Looking for boot catalog file %s\n",bootpath); -#endif - - if (!stat_filter(bootpath, &statbuf)) - { - /* - * make sure its big enough to hold what we want - */ - if (statbuf.st_size == 2048) - { - /* - * printf("Boot catalog exists, so we do nothing\n"); - */ - free(bootpath); - return; - } - else - { - fprintf (stderr, _("A boot catalog exists and appears corrupted.\n")); - fprintf (stderr, _("Please check the following file: %s.\n"), bootpath); - fprintf (stderr, _("This file must be removed before a bootable CD can be done.\n")); - free (bootpath); - exit (1); - } - } - - /* - * file does not exist, so we create it - * make it one CD sector long - */ - bcat = fopen (bootpath, "wb"); - if (bcat == NULL) - error (1, errno, _("Error creating boot catalog (%s)"), bootpath); - - buf = (char *) e_malloc( 2048 ); - if (fwrite (buf, 1, 2048, bcat) != 2048) - error (1, errno, _("Error writing to boot catalog (%s)"), bootpath); - fclose (bcat); - chmod (bootpath, S_IROTH | S_IRGRP | S_IRWXU); - - free(bootpath); -} /* init_boot_catalog(... */ - -void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) -{ - FILE *bootcat; - int checksum; - unsigned char * checksum_ptr; - struct directory_entry * de; - struct directory_entry * de2; - unsigned int i; - int nsectors; - - memset(boot_desc, 0, sizeof(*boot_desc)); - boot_desc->id[0] = 0; - memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - boot_desc->version[0] = 1; - - memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID)); - - /* - * search from root of iso fs to find boot catalog - */ - de2 = search_tree_file(root, boot_catalog); - if (!de2) - { - fprintf (stderr, _("Boot catalog cannot be found!\n")); - exit (1); - } - - set_731(boot_desc->bootcat_ptr, - (unsigned int) get_733(de2->isorec.extent)); - - /* - * now adjust boot catalog - * lets find boot image first - */ - de=search_tree_file(root, boot_image); - if (!de) - { - fprintf (stderr, _("Boot image cannot be found!\n")); - exit (1); - } - - /* - * we have the boot image, so write boot catalog information - * Next we write out the primary descriptor for the disc - */ - memset(&valid_desc, 0, sizeof(valid_desc)); - valid_desc.headerid[0] = 1; - valid_desc.arch[0] = EL_TORITO_ARCH_x86; - - /* - * we'll shove start of publisher id into id field, may get truncated - * but who really reads this stuff! - */ - if (publisher) - memcpy_max(valid_desc.id, publisher, MIN(23, strlen(publisher))); - - valid_desc.key1[0] = 0x55; - valid_desc.key2[0] = 0xAA; - - /* - * compute the checksum - */ - checksum=0; - checksum_ptr = (unsigned char *) &valid_desc; - for (i=0; isize + 511) & ~(511))/512; - fprintf (stderr, _("\nSize of boot image is %d sectors"), nsectors); - fprintf (stderr, " -> "); - - if (! use_eltorito_emul_floppy) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL; - fprintf (stderr, _("No emulation\n")); - } - else if (nsectors == 2880 ) - /* - * choose size of emulated floppy based on boot image size - */ - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP; - fprintf (stderr, _("Emulating a 1.44 meg floppy\n")); - } - else if (nsectors == 5760 ) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP; - fprintf (stderr, _("Emulating a 2.88 meg floppy\n")); - } - else if (nsectors == 2400 ) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP; - fprintf (stderr, _("Emulating a 1.2 meg floppy\n")); - } - else - { - fprintf (stderr, _("\nError - boot image is not the an allowable size.\n")); - exit (1); - } - - /* - * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! - */ - nsectors = 1; - set_721(default_desc.nsect, (unsigned int) nsectors ); -#ifdef DEBUG_TORITO - fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent)); -#endif - set_731(default_desc.bootoff, - (unsigned int) get_733(de->isorec.extent)); - - /* - * now write it to disk - */ - bootcat = fopen (de2->whole_name, "r+b"); - if (bootcat == NULL) - error (1, errno, _("Error opening boot catalog for update")); - - /* - * write out - */ - if (fwrite (&valid_desc, 1, 32, bootcat) != 32) - error (1, errno, _("Error writing to boot catalog")); - if (fwrite (&default_desc, 1, 32, bootcat) != 32) - error (1, errno, _("Error writing to boot catalog")); - fclose (bootcat); - - /* If the user has asked for it, patch the boot image */ - if (use_boot_info_table) - { - FILE *bootimage; - uint32_t bi_checksum; - unsigned int total_len; - static char csum_buffer[SECTOR_SIZE]; - int len; - struct eltorito_boot_info bi_table; - bootimage = fopen (de->whole_name, "r+b"); - if (bootimage == NULL) - error (1, errno, _("Error opening boot image file `%s' for update"), - de->whole_name); - /* Compute checksum of boot image, sans 64 bytes */ - total_len = 0; - bi_checksum = 0; - while ((len = fread (csum_buffer, 1, SECTOR_SIZE, bootimage)) > 0) - { - if (total_len & 3) - error (1, 0, _("Odd alignment at non-end-of-file in boot image `%s'"), - de->whole_name); - if (total_len < 64) - memset (csum_buffer, 0, 64 - total_len); - if (len < SECTOR_SIZE) - memset (csum_buffer + len, 0, SECTOR_SIZE - len); - for (i = 0; i < SECTOR_SIZE; i += 4) - bi_checksum += get_731 (&csum_buffer[i]); - total_len += len; - } - - if (total_len != de->size) - error (1, 0, _("Boot image file `%s' changed unexpectedly"), - de->whole_name); - /* End of file, set position to byte 8 */ - fseeko (bootimage, (off_t) 8, SEEK_SET); - memset (&bi_table, 0, sizeof (bi_table)); - /* Is it always safe to assume PVD is at session_start+16? */ - set_731 (bi_table.pvd_addr, session_start + 16); - set_731 (bi_table.file_addr, de->starting_block); - set_731 (bi_table.file_length, de->size); - set_731 (bi_table.file_checksum, bi_checksum); - - if (fwrite (&bi_table, 1, sizeof (bi_table), bootimage) != sizeof (bi_table)) - error (1, errno, _("Error writing to boot image (%s)"), bootimage); - fclose (bootimage); - } - -} /* get_torito_desc(... */ - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(tvd_write, FILE *, outfile) -{ - /* - * Next we write out the boot volume descriptor for the disc - */ - get_torito_desc(&gboot_desc); - xfwrite(&gboot_desc, 1, 2048, outfile); - last_extent_written ++; - return 0; -} - -struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write}; diff --git a/util/mkisofs/exclude.h b/util/mkisofs/exclude.h deleted file mode 100644 index ac1a561ad..000000000 --- a/util/mkisofs/exclude.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de: - * added 'exclude' option (-x) to specify pathnames NOT to be included in - * CD image. - * - * $Id: exclude.h,v 1.2 1999/03/02 03:41:25 eric Exp $ - */ - -void exclude __PR((char * fn)); -int is_excluded __PR((char * fn)); diff --git a/util/mkisofs/hash.c b/util/mkisofs/hash.c deleted file mode 100644 index 41e76b342..000000000 --- a/util/mkisofs/hash.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * File hash.c - generate hash tables for iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - 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, 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 "config.h" -#include "mkisofs.h" - -#define NR_HASH 1024 - -#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 2) + (INO << 8)) % NR_HASH) - -static struct file_hash * hash_table[NR_HASH] = {0,}; - -void FDECL1(add_hash, struct directory_entry *, spnt){ - struct file_hash * s_hash; - unsigned int hash_number; - - if(spnt->size == 0 || spnt->starting_block == 0) - if(spnt->size != 0 || spnt->starting_block != 0) { - fprintf(stderr,"Non zero-length file assigned zero extent.\n"); - exit(1); - }; - - if (spnt->dev == (dev_t) UNCACHED_DEVICE || spnt->inode == UNCACHED_INODE) return; - hash_number = HASH_FN((unsigned int) spnt->dev, (unsigned int) spnt->inode); - -#if 0 - if (verbose > 1) fprintf(stderr,"%s ",spnt->name); -#endif - s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash)); - s_hash->next = hash_table[hash_number]; - s_hash->inode = spnt->inode; - s_hash->dev = spnt->dev; - s_hash->starting_block = spnt->starting_block; - s_hash->size = spnt->size; - hash_table[hash_number] = s_hash; -} - -struct file_hash * FDECL2(find_hash, dev_t, dev, ino_t, inode){ - unsigned int hash_number; - struct file_hash * spnt; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL; - - spnt = hash_table[hash_number]; - while(spnt){ - if(spnt->inode == inode && spnt->dev == dev) return spnt; - spnt = spnt->next; - }; - return NULL; -} - - -static struct file_hash * directory_hash_table[NR_HASH] = {0,}; - -void FDECL2(add_directory_hash, dev_t, dev, ino_t, inode){ - struct file_hash * s_hash; - unsigned int hash_number; - - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - - s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash)); - s_hash->next = directory_hash_table[hash_number]; - s_hash->inode = inode; - s_hash->dev = dev; - directory_hash_table[hash_number] = s_hash; -} - -struct file_hash * FDECL2(find_directory_hash, dev_t, dev, ino_t, inode){ - unsigned int hash_number; - struct file_hash * spnt; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL; - - spnt = directory_hash_table[hash_number]; - while(spnt){ - if(spnt->inode == inode && spnt->dev == dev) return spnt; - spnt = spnt->next; - }; - return NULL; -} - -struct name_hash -{ - struct name_hash * next; - struct directory_entry * de; -}; - -#define NR_NAME_HASH 128 - -static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,}; - -/* - * Find the hash bucket for this name. - */ -static unsigned int FDECL1(name_hash, const char *, name) -{ - unsigned int hash = 0; - const char * p; - - p = name; - - while (*p) - { - /* - * Don't hash the iso9660 version number. This way - * we can detect duplicates in cases where we have - * directories (i.e. foo) and non-directories - * (i.e. foo;1). - */ - if( *p == ';' ) - { - break; - } - hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++; - } - return hash % NR_NAME_HASH; -} - -void FDECL1(add_file_hash, struct directory_entry *, de){ - struct name_hash * new; - int hash; - - new = (struct name_hash *) e_malloc(sizeof(struct name_hash)); - new->de = de; - new->next = NULL; - hash = name_hash(de->isorec.name); - - /* Now insert into the hash table */ - new->next = name_hash_table[hash]; - name_hash_table[hash] = new; -} - -struct directory_entry * FDECL1(find_file_hash, char *, name) -{ - struct name_hash * nh; - char * p1; - char * p2; - - for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next) - { - p1 = name; - p2 = nh->de->isorec.name; - - /* - * Look for end of string, or a mismatch. - */ - while(1==1) - { - if( (*p1 == '\0' || *p1 == ';') - || (*p2 == '\0' || *p2 == ';') - || (*p1 != *p2) ) - { - break; - } - p1++; - p2++; - } - - /* - * If we are at the end of both strings, then - * we have a match. - */ - if( (*p1 == '\0' || *p1 == ';') - && (*p2 == '\0' || *p2 == ';') ) - { - return nh->de; - } - } - return NULL; -} - -int FDECL1(delete_file_hash, struct directory_entry *, de){ - struct name_hash * nh, *prev; - int hash; - - prev = NULL; - hash = name_hash(de->isorec.name); - for(nh = name_hash_table[hash]; nh; nh = nh->next) { - if(nh->de == de) break; - prev = nh; - } - if(!nh) return 1; - if(!prev) - name_hash_table[hash] = nh->next; - else - prev->next = nh->next; - free(nh); - return 0; -} - -void flush_file_hash(){ - struct name_hash * nh, *nh1; - int i; - - for(i=0; inext; - free(nh); - nh = nh1; - } - name_hash_table[i] = NULL; - - } -} diff --git a/util/mkisofs/include/fctldefs.h b/util/mkisofs/include/fctldefs.h deleted file mode 100644 index de6b6a394..000000000 --- a/util/mkisofs/include/fctldefs.h +++ /dev/null @@ -1,57 +0,0 @@ -/* @(#)fctldefs.h 1.2 98/10/08 Copyright 1996 J. Schilling */ -/* - * Generic header for users of open(), creat() and chmod() - * - * Copyright (c) 1996 J. Schilling - */ -/* - * 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, 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _FCTLDEFS_H -#define _FCTLDEFS_H - -#ifndef _MCONFIG_H -#include -#endif - -#include -#include - -#ifdef HAVE_FCNTL_H - -# include - -#else /* HAVE_FCNTL_H */ - -# include - -#endif /* HAVE_FCNTL_H */ - -/* - * Do not define more than O_RDONLY / O_WRONLY / O_RDWR - * The values may differ. - */ -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif -#ifndef O_WRONLY -#define O_WRONLY 1 -#endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif - -#endif /* _FCTLDEFS_H */ diff --git a/util/mkisofs/include/mconfig.h b/util/mkisofs/include/mconfig.h deleted file mode 100644 index 1891d7ded..000000000 --- a/util/mkisofs/include/mconfig.h +++ /dev/null @@ -1,253 +0,0 @@ -/* @(#)mconfig.h 1.24 98/12/14 Copyright 1995 J. Schilling */ -/* - * definitions for machine configuration - * - * Copyright (c) 1995 J. Schilling - * - * This file must be included before any other file. - * Use only cpp instructions. - * - * NOTE: SING: (Schily Is Not Gnu) - */ -/* - * 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, 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _MCONFIG_H -#define _MCONFIG_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(unix) || defined(__unix) || defined(__unix__) -# define IS_UNIX -#endif - -#ifdef __MSDOS__ -# define IS_MSDOS -#endif - -#if defined(tos) || defined(__tos) -# define IS_TOS -#endif - -#ifdef THINK_C -# define IS_MAC -#endif - -#if defined(sun) || defined(__sun) || defined(__sun__) -# define IS_SUN -#endif - -#if defined(__CYGWIN32__) -# define IS_GCC_WIN32 -#endif - -/*--------------------------------------------------------------------------*/ -/* - * Some magic that cannot (yet) be figured out with autoconf. - */ - -#ifdef sparc -# ifndef HAVE_LDSTUB -# define HAVE_LDSTUB -# endif -# ifndef HAVE_SCANSTACK -# define HAVE_SCANSTACK -# endif -#endif -#if defined(__i386_) || defined(i386) -# ifndef HAVE_XCHG -# define HAVE_XCHG -# endif -# ifndef HAVE_SCANSTACK -# define HAVE_SCANSTACK -# endif -#endif - -#if defined(SOL2) || defined(SOL2) || defined(S5R4) || defined(__S5R4) \ - || defined(SVR4) -# ifndef __SVR4 -# define __SVR4 -# endif -#endif - -#ifdef __SVR4 -# ifndef SVR4 -# define SVR4 -# endif -#endif - -/* - * SunOS 4.x / SunOS 5.x - */ -#if defined(IS_SUN) -# define HAVE_GETAV0 -#endif - -/* - * AIX - */ -#if defined(_IBMR2) || defined(_AIX) -# define IS_UNIX /* ??? really ??? */ -#endif - -/* - * Silicon Graphics (must be before SVR4) - */ -#if defined(sgi) || defined(__sgi) -# define __NOT_SVR4__ /* Not a real SVR4 implementation */ -#endif - -/* - * Data General - */ -#if defined(__DGUX__) -#ifdef XXXXXXX -# undef HAVE_MTGET_DSREG -# undef HAVE_MTGET_RESID -# undef HAVE_MTGET_FILENO -# undef HAVE_MTGET_BLKNO -#endif -# define mt_type mt_model -# define mt_dsreg mt_status1 -# define mt_erreg mt_status2 - /* - * DGUX hides its flock as dg_flock. - */ -# define HAVE_FLOCK -# define flock dg_flock - /* - * Use the BSD style wait on DGUX to get the resource usages of child - * processes. - */ -# define _BSD_WAIT_FLAVOR -#endif - -/* - * Apple Rhapsody - */ -#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody -# define HAVE_OSDEF /* prevent later definitions to overwrite current */ -#endif - -/* - * NextStep - */ -#if defined(__NeXT__) && !defined(HAVE_OSDEF) -#define NO_PRINT_OVR -#undef HAVE_USG_STDIO /* - * NeXT Step 3.x uses __flsbuf(unsigned char , FILE *) - * instead of __flsbuf(int, FILE *) - */ -#endif - -/* - * NextStep 3.x has a broken linker that does not allow us to override - * these functions. - */ -#ifndef __OPRINTF__ - -#ifdef NO_PRINT_OVR -# define printf Xprintf -# define fprintf Xfprintf -# define sprintf Xsprintf -#endif - -#endif /* __OPRINTF__ */ - -/*--------------------------------------------------------------------------*/ -/* - * If there is no flock defined by the system, use emulation - * through fcntl record locking. - */ -#ifndef HAVE_FLOCK -#define LOCK_SH 1 /* shared lock */ -#define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* don't block when locking */ -#define LOCK_UN 8 /* unlock */ -#endif - -#include - -/* - * gcc 2.x generally implements the long long type. - */ -#ifdef __GNUC__ -# if __GNUC__ > 1 -# ifndef HAVE_LONGLONG -# define HAVE_LONGLONG -# endif -# endif -#endif - -/* - * Convert to GNU name - */ -#ifdef HAVE_STDC_HEADERS -# ifndef STDC_HEADERS -# define STDC_HEADERS -# endif -#endif -/* - * Convert to SCHILY name - */ -#ifdef STDC_HEADERS -# ifndef HAVE_STDC_HEADERS -# define HAVE_STDC_HEADERS -# endif -#endif - -#ifdef IS_UNIX -# define PATH_DELIM '/' -# define PATH_DELIM_STR "/" -# define far -# define near -#endif - -#ifdef IS_GCC_WIN32 -# define PATH_DELIM '/' -# define PATH_DELIM_STR "/" -# define far -# define near -#endif - -#ifdef IS_MSDOS -# define PATH_DELIM '\\' -# define PATH_DELIM_STR "\\" -#endif - -#ifdef IS_TOS -# define PATH_DELIM '\\' -# define PATH_DELIM_STR "\\" -# define far -# define near -#endif - -#ifdef IS_MAC -# define PATH_DELIM ':' -# define PATH_DELIM_STR ":" -# define far -# define near -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _MCONFIG_H */ diff --git a/util/mkisofs/include/prototyp.h b/util/mkisofs/include/prototyp.h deleted file mode 100644 index c74ae0af8..000000000 --- a/util/mkisofs/include/prototyp.h +++ /dev/null @@ -1,74 +0,0 @@ -/* @(#)prototyp.h 1.7 98/10/08 Copyright 1995 J. Schilling */ -/* - * Definitions for dealing with ANSI / KR C-Compilers - * - * Copyright (c) 1995 J. Schilling - */ -/* - * 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, 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _PROTOTYP_H -#define _PROTOTYP_H - -#ifndef PROTOTYPES - /* - * If this has already been defined, - * someone else knows better than us... - */ -# ifdef __STDC__ -# if __STDC__ /* ANSI C */ -# define PROTOTYPES -# endif -# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */ -# define PROTOTYPES -# endif -# endif -#endif /* PROTOTYPES */ - -/* - * If we have prototypes, we should have stdlib.h string.h stdarg.h - */ -#ifdef PROTOTYPES -#if !(defined(SABER) && defined(sun)) -# ifndef HAVE_STDARG_H -# define HAVE_STDARG_H -# endif -#endif -# ifndef HAVE_STDLIB_H -# define HAVE_STDLIB_H -# endif -# ifndef HAVE_STRING_H -# define HAVE_STRING_H -# endif -# ifndef HAVE_STDC_HEADERS -# define HAVE_STDC_HEADERS -# endif -# ifndef STDC_HEADERS -# define STDC_HEADERS /* GNU name */ -# endif -#endif - -#ifdef NO_PROTOTYPES /* Force not to use prototypes */ -# undef PROTOTYPES -#endif - -#ifdef PROTOTYPES -# define __PR(a) a -#else -# define __PR(a) () -#endif - -#endif /* _PROTOTYP_H */ diff --git a/util/mkisofs/include/statdefs.h b/util/mkisofs/include/statdefs.h deleted file mode 100644 index 0e34805ce..000000000 --- a/util/mkisofs/include/statdefs.h +++ /dev/null @@ -1,139 +0,0 @@ -/* @(#)statdefs.h 1.1 98/11/22 Copyright 1998 J. Schilling */ -/* - * Definitions for stat() file mode - * - * Copyright (c) 1998 J. Schilling - */ -/* - * 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, 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; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _STATDEFS_H -#define _STATDEFS_H - -#ifndef _MCONFIG_H -#include -#endif - -#ifdef STAT_MACROS_BROKEN -#undef S_ISFIFO /* Named pipe */ -#undef S_ISCHR /* Character special */ -#undef S_ISMPC /* UNUSED multiplexed c */ -#undef S_ISDIR /* Directory */ -#undef S_ISNAM /* Named file (XENIX) */ -#undef S_ISBLK /* Block special */ -#undef S_ISMPB /* UNUSED multiplexed b */ -#undef S_ISREG /* Regular file */ -#undef S_ISCNT /* Contiguous file */ -#undef S_ISLNK /* Symbolic link */ -#undef S_ISSHAD /* Solaris shadow inode */ -#undef S_ISSOCK /* UNIX domain socket */ -#undef S_ISDOOR /* Solaris DOOR */ -#endif - -#ifndef S_ISFIFO /* Named pipe */ -# ifdef S_IFIFO -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(m) (0) -# endif -#endif -#ifndef S_ISCHR /* Character special */ -# ifdef S_IFCHR -# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -# else -# define S_ISCHR(m) (0) -# endif -#endif -#ifndef S_ISMPC /* UNUSED multiplexed c */ -# ifdef S_IFMPC -# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -# else -# define S_ISMPC(m) (0) -# endif -#endif -#ifndef S_ISDIR /* Directory */ -# ifdef S_IFDIR -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -# else -# define S_ISDIR(m) (0) -# endif -#endif -#ifndef S_ISNAM /* Named file (XENIX) */ -# ifdef S_IFNAM -# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) -# else -# define S_ISNAM(m) (0) -# endif -#endif -#ifndef S_ISBLK /* Block special */ -# ifdef S_IFBLK -# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -# else -# define S_ISBLK(m) (0) -# endif -#endif -#ifndef S_ISMPB /* UNUSED multiplexed b */ -# ifdef S_IFMPB -# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -# else -# define S_ISMPB(m) (0) -# endif -#endif -#ifndef S_ISREG /* Regular file */ -# ifdef S_IFREG -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -# else -# define S_ISREG(m) (0) -# endif -#endif -#ifndef S_ISCNT /* Contiguous file */ -# ifdef S_IFCNT -# define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT) -# else -# define S_ISCNT(m) (0) -# endif -#endif -#ifndef S_ISLNK /* Symbolic link */ -# ifdef S_IFLNK -# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -# else -# define S_ISLNK(m) (0) -# endif -#endif -#ifndef S_ISSHAD /* Solaris shadow inode */ -# ifdef S_IFSHAD -# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD) -# else -# define S_ISSHAD(m) (0) -# endif -#endif -#ifndef S_ISSOCK /* UNIX domain socket */ -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) (0) -# endif -#endif -#ifndef S_ISDOOR /* Solaris DOOR */ -# ifdef S_IFDOOR -# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) -# else -# define S_ISDOOR(m) (0) -# endif -#endif - -#endif /* _STATDEFS_H */ - diff --git a/util/mkisofs/iso9660.h b/util/mkisofs/iso9660.h deleted file mode 100644 index 78a05db92..000000000 --- a/util/mkisofs/iso9660.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Header file iso9660.h - assorted structure definitions and typecasts. - * specific to iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 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, 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 . - */ - -/* - * $Id: iso9660.h,v 1.2 1997/05/17 15:46:44 eric Exp $ - */ - -#ifndef _ISOFS_FS_H -#define _ISOFS_FS_H - -/* - * The isofs filesystem constants/structures - */ - -/* This part borrowed from the bsd386 isofs */ -#define ISODCL(from, to) (to - from + 1) - -struct iso_volume_descriptor { - char type[ISODCL(1,1)]; /* 711 */ - char id[ISODCL(2,6)]; - char version[ISODCL(7,7)]; - char data[ISODCL(8,2048)]; -}; - -/* volume descriptor types */ -#define ISO_VD_PRIMARY 1 -#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */ -#define ISO_VD_END 255 - -#define ISO_STANDARD_ID "CD001" - -#define EL_TORITO_ID "EL TORITO SPECIFICATION" -#define EL_TORITO_ARCH_x86 0 -#define EL_TORITO_ARCH_PPC 1 -#define EL_TORITO_ARCH_MAC 2 -#define EL_TORITO_BOOTABLE 0x88 -#define EL_TORITO_MEDIA_NOEMUL 0 -#define EL_TORITO_MEDIA_12FLOP 1 -#define EL_TORITO_MEDIA_144FLOP 2 -#define EL_TORITO_MEDIA_288FLOP 3 -#define EL_TORITO_MEDIA_HD 4 - -struct iso_primary_descriptor { - char type [ISODCL ( 1, 1)]; /* 711 */ - char id [ISODCL ( 2, 6)]; - char version [ISODCL ( 7, 7)]; /* 711 */ - char unused1 [ISODCL ( 8, 8)]; - char system_id [ISODCL ( 9, 40)]; /* achars */ - char volume_id [ISODCL ( 41, 72)]; /* dchars */ - char unused2 [ISODCL ( 73, 80)]; - char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ - char escape_sequences [ISODCL ( 89, 120)]; - char volume_set_size [ISODCL (121, 124)]; /* 723 */ - char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ - char logical_block_size [ISODCL (129, 132)]; /* 723 */ - char path_table_size [ISODCL (133, 140)]; /* 733 */ - char type_l_path_table [ISODCL (141, 144)]; /* 731 */ - char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ - char type_m_path_table [ISODCL (149, 152)]; /* 732 */ - char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ - char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ - char volume_set_id [ISODCL (191, 318)]; /* dchars */ - char publisher_id [ISODCL (319, 446)]; /* achars */ - char preparer_id [ISODCL (447, 574)]; /* achars */ - char application_id [ISODCL (575, 702)]; /* achars */ - char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ - char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ - char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ - char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ - char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ - char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ - char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ - char file_structure_version [ISODCL (882, 882)]; /* 711 */ - char unused4 [ISODCL (883, 883)]; - char application_data [ISODCL (884, 1395)]; - char unused5 [ISODCL (1396, 2048)]; -}; - -/* El Torito Boot Record Volume Descriptor */ -struct eltorito_boot_descriptor { - char id [ISODCL ( 1, 1)]; /* 711 */ - char id2 [ISODCL ( 2, 6)]; - char version [ISODCL ( 7, 7)]; /* 711 */ - char system_id [ISODCL ( 8, 39)]; - char unused2 [ISODCL ( 40, 71)]; - char bootcat_ptr [ISODCL ( 72 , 75)]; - char unused5 [ISODCL ( 76, 2048)]; -}; - -/* Validation entry for El Torito */ -struct eltorito_validation_entry { - char headerid [ISODCL ( 1, 1)]; /* 711 */ - char arch [ISODCL ( 2, 2)]; - char pad1 [ISODCL ( 3, 4)]; /* 711 */ - char id [ISODCL ( 5, 28)]; - char cksum [ISODCL ( 29, 30)]; - char key1 [ISODCL ( 31, 31)]; - char key2 [ISODCL ( 32, 32)]; -}; - -/* El Torito initial/default entry in boot catalog */ -struct eltorito_defaultboot_entry { - char boot_id [ISODCL ( 1, 1)]; /* 711 */ - char boot_media [ISODCL ( 2, 2)]; - char loadseg [ISODCL ( 3, 4)]; /* 711 */ - char arch [ISODCL ( 5, 5)]; - char pad1 [ISODCL ( 6, 6)]; - char nsect [ISODCL ( 7, 8)]; - char bootoff [ISODCL ( 9, 12)]; - char pad2 [ISODCL ( 13, 32)]; -}; - -/* El Torito boot information table */ -struct eltorito_boot_info -{ - /* Address of Primary Volume Descriptor. */ - char pvd_addr[ISODCL (1, 4)]; - /* Boot file address. */ - char file_addr[ISODCL (5, 8)]; - /* Boot file length. */ - char file_length[ISODCL (9, 12)]; - /* Boot file checksum. */ - char file_checksum[ISODCL (13, 16)]; - char dummy[ISODCL (17, 56)]; -}; - - -/* We use this to help us look up the parent inode numbers. */ - -struct iso_path_table{ - unsigned char name_len[2]; /* 721 */ - char extent[4]; /* 731 */ - char parent[2]; /* 721 */ - char name[1]; -}; - -struct iso_directory_record { - unsigned char length [ISODCL (1, 1)]; /* 711 */ - char ext_attr_length [ISODCL (2, 2)]; /* 711 */ - char extent [ISODCL (3, 10)]; /* 733 */ - char size [ISODCL (11, 18)]; /* 733 */ - char date [ISODCL (19, 25)]; /* 7 by 711 */ - char flags [ISODCL (26, 26)]; - char file_unit_size [ISODCL (27, 27)]; /* 711 */ - char interleave [ISODCL (28, 28)]; /* 711 */ - char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ - unsigned char name_len [ISODCL (33, 33)]; /* 711 */ - char name [34]; /* Not really, but we need something here */ -}; -#endif - - - diff --git a/util/mkisofs/joliet.c b/util/mkisofs/joliet.c deleted file mode 100644 index b3c755792..000000000 --- a/util/mkisofs/joliet.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * File joliet.c - handle Win95/WinNT long file/unicode extensions for iso9660. - - Copyright 1997 Eric Youngdale. - - Copyright (C) 2009 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, 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 . - */ - -/* - * Joliet extensions for ISO9660. These are spottily documented by - * Microsoft. In their infinite stupidity, they completely ignored - * the possibility of using an SUSP record with the long filename - * in it, and instead wrote out a duplicate directory tree with the - * long filenames in it. - * - * I am not sure why they did this. One reason is that they get the path - * tables with the long filenames in them. - * - * There are two basic principles to Joliet, and the non-Unicode variant - * known as Romeo. Long filenames seem to be the main one, and the second - * is that the character set and a few other things is substantially relaxed. - * - * The SVD is identical to the PVD, except: - * - * Id is 2, not 1 (indicates SVD). - * escape_sequences contains UCS-2 indicator (levels 1, 2 or 3). - * The root directory record points to a different extent (with different - * size). - * There are different path tables for the two sets of directory trees. - * - * The following fields are recorded in Unicode: - * system_id - * volume_id - * volume_set_id - * publisher_id - * preparer_id - * application_id - * copyright_file_id - * abstract_file_id - * bibliographic_file_id - * - * Unicode strings are always encoded in big-endian format. - * - * In a directory record, everything is the same as with iso9660, except - * that the name is recorded in unicode. The name length is specified in - * total bytes, not in number of unicode characters. - * - * The character set used for the names is different with UCS - the - * restrictions are that the following are not allowed: - * - * Characters (00)(00) through (00)(1f) (control chars) - * (00)(2a) '*' - * (00)(2f) '/' - * (00)(3a) ':' - * (00)(3b) ';' - * (00)(3f) '?' - * (00)(5c) '\' - */ -#include "config.h" -#include "mkisofs.h" -#include "iso9660.h" - -#include -#include -#include - -static unsigned int jpath_table_index; -static struct directory ** jpathlist; -static int next_jpath_index = 1; -static int sort_goof; - -static int generate_joliet_path_tables __PR((void)); -static int DECL(joliet_sort_directory, (struct directory_entry ** sort_dir)); -static void DECL(assign_joliet_directory_addresses, (struct directory * node)); -static int jroot_gen __PR((void)); - -/* - * Function: convert_to_unicode - * - * Purpose: Perform a 1/2 assed unicode conversion on a text - * string. - * - * Notes: - */ -static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char *, source ) -{ - unsigned char * tmpbuf; - int i; - int j; - - /* - * If we get a NULL pointer for the source, it means we have an inplace - * copy, and we need to make a temporary working copy first. - */ - if( source == NULL ) - { - tmpbuf = (uint8_t *) e_malloc(size); - memcpy( tmpbuf, buffer, size); - } - else - { - tmpbuf = (uint8_t *)source; - } - - /* - * Now start copying characters. If the size was specified to be 0, then - * assume the input was 0 terminated. - */ - j = 0; - for(i=0; i < size ; i += 2, j++) - { - buffer[i] = 0; - /* - * JS integrated from: Achim_Kaiser@t-online.de - * - * Let all valid unicode characters pass through (assuming ISO-8859-1). - * Others are set to '_' . - */ - if( tmpbuf[j] != 0 && - (tmpbuf[j] <= 0x1f || (tmpbuf[j] >= 0x7F && tmpbuf[j] <= 0xA0)) ) - { - buffer[i+1] = '_'; - } - else - { - switch(tmpbuf[j]) - { - case '*': - case '/': - case ':': - case ';': - case '?': - case '\\': - /* - * Even Joliet has some standards as to what is allowed in a pathname. - * Pretty tame in comparison to what DOS restricts you to. - */ - buffer[i+1] = '_'; - break; - default: - buffer[i+1] = tmpbuf[j]; - break; - } - } - } - - if( source == NULL ) - { - free(tmpbuf); - } -} - -/* - * Function: joliet_strlen - * - * Purpose: Return length in bytes of string after conversion to unicode. - * - * Notes: This is provided mainly as a convenience so that when more intelligent - * Unicode conversion for either Multibyte or 8-bit codes is available that - * we can easily adapt. - */ -static int FDECL1(joliet_strlen, const char *, string) -{ - int rtn; - - rtn = strlen(string) << 1; - - /* - * We do clamp the maximum length of a Joliet string to be the - * maximum path size. This helps to ensure that we don't completely - * bolix things up with very long paths. The Joliet specs say - * that the maximum length is 128 bytes, or 64 unicode characters. - */ - if( rtn > 0x80) - { - rtn = 0x80; - } - return rtn; -} - -/* - * Function: get_joliet_vol_desc - * - * Purpose: generate a Joliet compatible volume desc. - * - * Notes: Assume that we have the non-joliet vol desc - * already present in the buffer. Just modifiy the - * appropriate fields. - */ -static void FDECL1(get_joliet_vol_desc, struct iso_primary_descriptor *, jvol_desc) -{ - jvol_desc->type[0] = ISO_VD_SUPPLEMENTARY; - - /* - * For now, always do Unicode level 3. I don't really know what 1 and 2 - * are - perhaps a more limited Unicode set. - * - * FIXME(eric) - how does Romeo fit in here? As mkisofs just - * "expands" 8 bit character codes to 16 bits and does nothing - * special with the Unicode characters, therefore shouldn't mkisofs - * really be stating that it's using UCS-2 Level 1, not Level 3 for - * the Joliet directory tree. - */ - strcpy(jvol_desc->escape_sequences, "%/@"); - - /* - * Until we have Unicode path tables, leave these unset. - */ - set_733((char *) jvol_desc->path_table_size, jpath_table_size); - set_731(jvol_desc->type_l_path_table, jpath_table[0]); - set_731(jvol_desc->opt_type_l_path_table, jpath_table[1]); - set_732(jvol_desc->type_m_path_table, jpath_table[2]); - set_732(jvol_desc->opt_type_m_path_table, jpath_table[3]); - - /* - * Set this one up. - */ - memcpy(jvol_desc->root_directory_record, &jroot_record, - sizeof(struct iso_directory_record)); - - /* - * Finally, we have a bunch of strings to convert to Unicode. - * FIXME(eric) - I don't know how to do this in general, so we will - * just be really lazy and do a char -> short conversion. We probably - * will want to filter any characters >= 0x80. - */ - convert_to_unicode((uint8_t *)jvol_desc->system_id, sizeof(jvol_desc->system_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->volume_id, sizeof(jvol_desc->volume_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->volume_set_id, sizeof(jvol_desc->volume_set_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->publisher_id, sizeof(jvol_desc->publisher_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->preparer_id, sizeof(jvol_desc->preparer_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->application_id, sizeof(jvol_desc->application_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->copyright_file_id, sizeof(jvol_desc->copyright_file_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->abstract_file_id, sizeof(jvol_desc->abstract_file_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->bibliographic_file_id, sizeof(jvol_desc->bibliographic_file_id), NULL); - - -} - -static void FDECL1(assign_joliet_directory_addresses, struct directory *, node) -{ - int dir_size; - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - /* - * If we already have an extent for this (i.e. it came from - * a multisession disc), then don't reassign a new extent. - */ - dpnt->jpath_index = next_jpath_index++; - if( dpnt->jextent == 0 ) - { - dpnt->jextent = last_extent; - dir_size = (dpnt->jsize + (SECTOR_SIZE - 1)) >> 11; - last_extent += dir_size; - } - } - - /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) - { - assign_joliet_directory_addresses(dpnt->subdir); - } - dpnt = dpnt->next; - } -} - -static -void FDECL1(build_jpathlist, struct directory *, node) -{ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - jpathlist[dpnt->jpath_index] = dpnt; - } - if(dpnt->subdir) build_jpathlist(dpnt->subdir); - dpnt = dpnt->next; - } -} /* build_jpathlist(... */ - -static int FDECL2(joliet_compare_paths, void const *, r, void const *, l) -{ - struct directory const *ll = *(struct directory * const *)l; - struct directory const *rr = *(struct directory * const *)r; - int rparent, lparent; - - rparent = rr->parent->jpath_index; - lparent = ll->parent->jpath_index; - if( rr->parent == reloc_dir ) - { - rparent = rr->self->parent_rec->filedir->jpath_index; - } - - if( ll->parent == reloc_dir ) - { - lparent = ll->self->parent_rec->filedir->jpath_index; - } - - if (rparent < lparent) - { - return -1; - } - - if (rparent > lparent) - { - return 1; - } - - return strcmp(rr->self->name, ll->self->name); - -} /* compare_paths(... */ - -static int generate_joliet_path_tables() -{ - struct directory_entry * de; - struct directory * dpnt; - int fix; - int j; - int namelen; - char * npnt; - char * npnt1; - int tablesize; - - /* - * First allocate memory for the tables and initialize the memory - */ - tablesize = jpath_blocks << 11; - jpath_table_m = (char *) e_malloc(tablesize); - jpath_table_l = (char *) e_malloc(tablesize); - memset(jpath_table_l, 0, tablesize); - memset(jpath_table_m, 0, tablesize); - - if( next_jpath_index > 0xffff ) - { - fprintf (stderr, _("Unable to generate sane path tables - too many directories (%d)\n"), - next_jpath_index); - exit (1); - } - /* - * Now start filling in the path tables. Start with root directory - */ - jpath_table_index = 0; - jpathlist = (struct directory **) e_malloc(sizeof(struct directory *) - * next_jpath_index); - memset(jpathlist, 0, sizeof(struct directory *) * next_jpath_index); - build_jpathlist(root); - - do - { - fix = 0; -#ifdef __STDC__ - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), - (int (*)(const void *, const void *))joliet_compare_paths); -#else - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), - joliet_compare_paths); -#endif - - for(j=1; jjpath_index != j) - { - jpathlist[j]->jpath_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_name; - - npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { - npnt = npnt1 + 1; - } - - de = dpnt->self; - if(!de) - { - fprintf (stderr, _("Fatal goof - directory has amnesia\n")); - exit (1); - } - - namelen = joliet_strlen(de->name); - - if( dpnt == root ) - { - jpath_table_l[jpath_table_index] = 1; - jpath_table_m[jpath_table_index] = 1; - } - else - { - jpath_table_l[jpath_table_index] = namelen; - jpath_table_m[jpath_table_index] = namelen; - } - jpath_table_index += 2; - - set_731(jpath_table_l + jpath_table_index, dpnt->jextent); - set_732(jpath_table_m + jpath_table_index, dpnt->jextent); - jpath_table_index += 4; - - if( dpnt->parent != reloc_dir ) - { - set_721(jpath_table_l + jpath_table_index, - dpnt->parent->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->parent->jpath_index); - } - else - { - set_721(jpath_table_l + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); - } - - jpath_table_index += 2; - - /* - * The root directory is still represented in non-unicode fashion. - */ - if( dpnt == root ) - { - jpath_table_l[jpath_table_index] = 0; - jpath_table_m[jpath_table_index] = 0; - jpath_table_index ++; - } - else - { - convert_to_unicode((uint8_t *)jpath_table_l + jpath_table_index, - namelen, de->name); - convert_to_unicode((uint8_t *)jpath_table_m + jpath_table_index, - namelen, de->name); - jpath_table_index += namelen; - } - - if(jpath_table_index & 1) - { - jpath_table_index++; /* For odd lengths we pad */ - } - } - - free(jpathlist); - if(jpath_table_index != jpath_table_size) - { - fprintf(stderr, _("Joliet path table lengths do not match %d %d\n"), - jpath_table_index, - jpath_table_size); - } - return 0; -} /* generate_path_tables(... */ - -static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE *, outfile) -{ - unsigned int dir_index; - char * directory_buffer; - int new_reclen; - struct directory_entry * s_entry; - struct directory_entry * s_entry1; - struct iso_directory_record jrec; - unsigned int total_size; - int cvt_len; - struct directory * finddir; - - total_size = (dpnt->jsize + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - directory_buffer = (char *) e_malloc(total_size); - memset(directory_buffer, 0, total_size); - dir_index = 0; - - s_entry = dpnt->jcontents; - while(s_entry) - { - if(s_entry->de_flags & INHIBIT_JOLIET_ENTRY) { - s_entry = s_entry->jnext; - continue; - } - - /* - * If this entry was a directory that was relocated, we have a bit - * of trouble here. We need to dig out the real thing and put it - * back here. In the Joliet tree, there is no relocated rock - * ridge, as there are no depth limits to a directory tree. - */ - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 ) - { - for(s_entry1 = reloc_dir->contents; s_entry1; s_entry1 = s_entry1->next) - { - if( s_entry1->parent_rec == s_entry ) - { - break; - } - } - if( s_entry1 == NULL ) - { - /* - * We got trouble. - */ - fprintf (stderr, _("Unable to locate relocated directory\n")); - exit (1); - } - } - else - { - s_entry1 = s_entry; - } - - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector - */ - new_reclen = s_entry1->jreclen; - if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) - { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - - memcpy(&jrec, &s_entry1->isorec, sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name)); - - cvt_len = joliet_strlen(s_entry1->name); - - /* - * Fix the record length - this was the non-Joliet version we - * were seeing. - */ - jrec.name_len[0] = cvt_len; - jrec.length[0] = s_entry1->jreclen; - - /* - * If this is a directory, fix the correct size and extent - * number. - */ - if( (jrec.flags[0] & 2) != 0 ) - { - if(strcmp(s_entry1->name,".") == 0) - { - jrec.name_len[0] = 1; - set_733((char *) jrec.extent, dpnt->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->jsize)); - } - else if(strcmp(s_entry1->name,"..") == 0) - { - jrec.name_len[0] = 1; - if( dpnt->parent == reloc_dir ) - { - set_733((char *) jrec.extent, dpnt->self->parent_rec->filedir->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->self->parent_rec->filedir->jsize)); - } - else - - { - set_733((char *) jrec.extent, dpnt->parent->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->parent->jsize)); - } - } - else - { - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 ) - { - finddir = reloc_dir->subdir; - } - else - { - finddir = dpnt->subdir; - } - while(1==1) - { - if(finddir->self == s_entry1) break; - finddir = finddir->next; - if(!finddir) - { - fprintf (stderr, _("Fatal goof - unable to find directory location\n")); - exit (1); - } - } - set_733((char *) jrec.extent, finddir->jextent); - set_733((char *) jrec.size, ROUND_UP(finddir->jsize)); - } - } - - memcpy(directory_buffer + dir_index, &jrec, - sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name)); - - - dir_index += sizeof(struct iso_directory_record) - - sizeof (s_entry1->isorec.name); - - /* - * Finally dump the Unicode version of the filename. - * Note - . and .. are the same as with non-Joliet discs. - */ - if( (jrec.flags[0] & 2) != 0 - && strcmp(s_entry1->name, ".") == 0 ) - { - directory_buffer[dir_index++] = 0; - } - else if( (jrec.flags[0] & 2) != 0 - && strcmp(s_entry1->name, "..") == 0 ) - { - directory_buffer[dir_index++] = 1; - } - else - { - convert_to_unicode((uint8_t *)directory_buffer + dir_index, - cvt_len, - s_entry1->name); - dir_index += cvt_len; - } - - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - s_entry = s_entry->jnext; - } - - if(dpnt->jsize != dir_index) - { - fprintf (stderr, _("Unexpected joliet directory length %d %d %s\n"), - dpnt->jsize, dir_index, dpnt->de_name); - } - - xfwrite(directory_buffer, 1, total_size, outfile); - last_extent_written += total_size >> 11; - free(directory_buffer); -} /* generate_one_joliet_directory(... */ - -static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) -{ - struct directory_entry * s_entry; - int status = 0; - - /* don't want to skip this directory if it's the reloc_dir at the moment */ - if(this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) - { - return 0; - } - - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* skip hidden entries */ - if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - continue; - } - - /* - * First update the path table sizes for directories. - * - * Finally, set the length of the directory entry if Joliet is used. - * The name is longer, but no Rock Ridge is ever used here, so - * depending upon the options the entry size might turn out to be about - * the same. The Unicode name is always a multiple of 2 bytes, so - * we always add 1 to make it an even number. - */ - if(s_entry->isorec.flags[0] == 2) - { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - jpath_table_size += joliet_strlen(s_entry->name) + sizeof(struct iso_path_table) - 1; - if (jpath_table_size & 1) - { - jpath_table_size++; - } - } - else - { - if (this_dir == root && strlen(s_entry->name) == 1) - { - jpath_table_size += sizeof(struct iso_path_table); - if (jpath_table_size & 1) jpath_table_size++; - } - } - } - - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - s_entry->jreclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) - + joliet_strlen(s_entry->name) - + 1; - } - else - { - /* - * Special - for '.' and '..' we generate the same records we - * did for non-Joliet discs. - */ - s_entry->jreclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) - + 1; - } - - - } - - if( (this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - return 0; - } - - this_dir->jcontents = this_dir->contents; - status = joliet_sort_directory(&this_dir->jcontents); - - /* - * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary - */ - s_entry = this_dir->jcontents; -/* - * XXX Is it ok to comment this out? - */ -/*XXX JS this_dir->ce_bytes = 0;*/ - for(s_entry = this_dir->jcontents; s_entry; s_entry = s_entry->jnext) - { - int jreclen; - - if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - continue; - } - - jreclen = s_entry->jreclen; - - if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= SECTOR_SIZE) - { - this_dir->jsize = (this_dir->jsize + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - this_dir->jsize += jreclen; - } - return status; -} - -/* - * Similar to the iso9660 case, except here we perform a full sort based upon the - * regular name of the file, not the 8.3 version. - */ -static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) -{ - char * rpnt, *lpnt; - struct directory_entry ** r, **l; - - r = (struct directory_entry **) rr; - l = (struct directory_entry **) ll; - rpnt = (*r)->name; - lpnt = (*l)->name; - - /* - * If the entries are the same, this is an error. - */ - if( strcmp(rpnt, lpnt) == 0 ) - { - sort_goof++; - } - - /* - * Put the '.' and '..' entries on the head of the sorted list. - * For normal ASCII, this always happens to be the case, but out of - * band characters cause this not to be the case sometimes. - */ - if( strcmp(rpnt, ".") == 0 ) return -1; - if( strcmp(lpnt, ".") == 0 ) return 1; - - if( strcmp(rpnt, "..") == 0 ) return -1; - if( strcmp(lpnt, "..") == 0 ) return 1; - - while(*rpnt && *lpnt) - { - if(*rpnt == ';' && *lpnt != ';') return -1; - if(*rpnt != ';' && *lpnt == ';') return 1; - - if(*rpnt == ';' && *lpnt == ';') return 0; - - /* - * Extensions are not special here. Don't treat the dot as something that - * must be bumped to the start of the list. - */ -#if 0 - if(*rpnt == '.' && *lpnt != '.') return -1; - if(*rpnt != '.' && *lpnt == '.') return 1; -#endif - - if(*rpnt < *lpnt) return -1; - if(*rpnt > *lpnt) return 1; - rpnt++; lpnt++; - } - if(*rpnt) return 1; - if(*lpnt) return -1; - return 0; -} - - -/* - * Function: sort_directory - * - * Purpose: Sort the directory in the appropriate ISO9660 - * order. - * - * Notes: Returns 0 if OK, returns > 0 if an error occurred. - */ -static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir) -{ - int dcount = 0; - int i; - struct directory_entry * s_entry; - struct directory_entry ** sortlist; - - s_entry = *sort_dir; - while(s_entry) - { - /* skip hidden entries */ - if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) - dcount++; - s_entry = s_entry->next; - } - - /* - * OK, now we know how many there are. Build a vector for sorting. - */ - sortlist = (struct directory_entry **) - e_malloc(sizeof(struct directory_entry *) * dcount); - - dcount = 0; - s_entry = *sort_dir; - while(s_entry) - { - /* skip hidden entries */ - if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) { - sortlist[dcount] = s_entry; - dcount++; - } - s_entry = s_entry->next; - } - - sort_goof = 0; -#ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), - (int (*)(const void *, const void *))joliet_compare_dirs); -#else - qsort(sortlist, dcount, sizeof(struct directory_entry *), - joliet_compare_dirs); -#endif - - /* - * Now reassemble the linked list in the proper sorted order - */ - for(i=0; ijnext = sortlist[i+1]; - } - - sortlist[dcount-1]->jnext = NULL; - *sort_dir = sortlist[0]; - - free(sortlist); - return sort_goof; -} - -int FDECL1(joliet_sort_tree, struct directory *, node) -{ - struct directory * dpnt; - int ret = 0; - - dpnt = node; - - while (dpnt){ - ret = joliet_sort_n_finish(dpnt); - if( ret ) - { - break; - } - if(dpnt->subdir) ret = joliet_sort_tree(dpnt->subdir); - if( ret ) - { - break; - } - dpnt = dpnt->next; - } - return ret; -} - -static void FDECL2(generate_joliet_directories, struct directory *, node, FILE*, outfile){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - /* - * In theory we should never reuse a directory, so this doesn't - * make much sense. - */ - if( dpnt->jextent > session_start ) - { - generate_one_joliet_directory(dpnt, outfile); - } - } - /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) - generate_joliet_directories(dpnt->subdir, outfile); - dpnt = dpnt->next; - } -} - - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(jpathtab_write, FILE *, outfile) -{ - /* - * Next we write the path tables - */ - xfwrite(jpath_table_l, 1, jpath_blocks << 11, outfile); - xfwrite(jpath_table_m, 1, jpath_blocks << 11, outfile); - last_extent_written += 2*jpath_blocks; - free(jpath_table_l); - free(jpath_table_m); - jpath_table_l = NULL; - jpath_table_m = NULL; - return 0; -} - -static int FDECL1(jdirtree_size, int, starting_extent) -{ - assign_joliet_directory_addresses(root); - return 0; -} - -static int jroot_gen() -{ - jroot_record.length[0] = 1 + sizeof(struct iso_directory_record) - - sizeof(jroot_record.name); - jroot_record.ext_attr_length[0] = 0; - set_733((char *) jroot_record.extent, root->jextent); - set_733((char *) jroot_record.size, ROUND_UP(root->jsize)); - iso9660_date(jroot_record.date, root_statbuf.st_mtime); - jroot_record.flags[0] = 2; - jroot_record.file_unit_size[0] = 0; - jroot_record.interleave[0] = 0; - set_723(jroot_record.volume_sequence_number, volume_sequence_number); - jroot_record.name_len[0] = 1; - return 0; -} - -static int FDECL1(jdirtree_write, FILE *, outfile) -{ - generate_joliet_directories(root, outfile); - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(jvd_write, FILE *, outfile) -{ - struct iso_primary_descriptor jvol_desc; - - /* - * Next we write out the boot volume descriptor for the disc - */ - jvol_desc = vol_desc; - get_joliet_vol_desc(&jvol_desc); - xfwrite(&jvol_desc, 1, 2048, outfile); - last_extent_written ++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ -static int FDECL1(jpathtab_size, int, starting_extent) -{ - jpath_table[0] = starting_extent; - jpath_table[1] = 0; - jpath_table[2] = jpath_table[0] + jpath_blocks; - jpath_table[3] = 0; - - last_extent += 2*jpath_blocks; - return 0; -} - -struct output_fragment joliet_desc = {NULL, oneblock_size, jroot_gen,jvd_write}; -struct output_fragment jpathtable_desc= {NULL, jpathtab_size, generate_joliet_path_tables, jpathtab_write}; -struct output_fragment jdirtree_desc = {NULL, jdirtree_size, NULL, jdirtree_write}; diff --git a/util/mkisofs/match.c b/util/mkisofs/match.c deleted file mode 100644 index 0072b504e..000000000 --- a/util/mkisofs/match.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2009 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 "config.h" - -#include -#include -#include "fnmatch.h" - -#include "match.h" - -struct pattern -{ - char *str; - struct pattern *next; -}; - -static struct pattern *patlist = NULL; -static struct pattern *i_patlist = NULL; /* ISO9660/RR */ -static struct pattern *j_patlist = NULL; /* Joliet */ - -#define DECL_ADD_MATCH(function, list) \ -void \ -function (char *pattern) \ -{ \ - struct pattern *new; \ - new = malloc (sizeof (*new)); \ - new->str = strdup (pattern); \ - new->next = list; \ - list = new; \ -} - -DECL_ADD_MATCH (add_match, patlist) -DECL_ADD_MATCH (i_add_match, i_patlist) -DECL_ADD_MATCH (j_add_match, j_patlist) - -#define DECL_MATCHES(function, list) \ -int \ -function (char *str) \ -{ \ - struct pattern *i; \ - for (i = list; i != NULL; i = i->next) \ - if (fnmatch (i->str, str, FNM_FILE_NAME) != FNM_NOMATCH) \ - return 1; \ - return 0; \ -} - -DECL_MATCHES (matches, patlist) -DECL_MATCHES (i_matches, i_patlist) -DECL_MATCHES (j_matches, j_patlist) - -int -i_ishidden() -{ - return (i_patlist != NULL); -} - - -int j_ishidden() -{ - return (j_patlist != NULL); -} diff --git a/util/mkisofs/match.h b/util/mkisofs/match.h deleted file mode 100644 index ee346a24c..000000000 --- a/util/mkisofs/match.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2009 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 "config.h" - -extern void add_match (char *); -extern void i_add_match (char *); -extern void j_add_match (char *); - -extern int matches (char *); -extern int i_matches (char *); -extern int j_matches (char *); - -extern int i_ishidden (); -extern int j_ishidden (); diff --git a/util/mkisofs/mkisofs.c b/util/mkisofs/mkisofs.c deleted file mode 100644 index 16e2f0c7d..000000000 --- a/util/mkisofs/mkisofs.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* - * Program mkisofs.c - generate iso9660 filesystem based upon directory - * tree on hard disk. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 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, 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 "config.h" -#include "mkisofs.h" -#include "match.h" -#include "getopt.h" - -#include "iso9660.h" -#include - -#ifndef VMS -#include -#else -#include -#include "vms.h" -#endif - -#include -#include - -#ifndef VMS -#ifdef HAVE_UNISTD_H -#include -#endif -#endif -#include - -#include "exclude.h" - -#ifdef __NetBSD__ -#include -#include -#endif - -struct directory * root = NULL; - -static char version_string[] = "mkisofs 1.12b5"; - -#include "progname.h" - -char * outfile; -FILE * discimage; -uint64_t next_extent = 0; -uint64_t last_extent = 0; -uint64_t session_start = 0; -unsigned int path_table_size = 0; -unsigned int path_table[4] = {0,}; -unsigned int path_blocks = 0; - - -unsigned int jpath_table_size = 0; -unsigned int jpath_table[4] = {0,}; -unsigned int jpath_blocks = 0; - -struct iso_directory_record root_record; -struct iso_directory_record jroot_record; - -char * extension_record = NULL; -int extension_record_extent = 0; -int extension_record_size = 0; - -/* These variables are associated with command line options */ -int use_eltorito = 0; -int use_eltorito_emul_floppy = 0; -int use_embedded_boot = 0; -int use_protective_msdos_label = 0; -int use_boot_info_table = 0; -int use_RockRidge = 0; -int use_Joliet = 0; -int verbose = 1; -int all_files = 0; -int follow_links = 0; -int rationalize = 0; -int generate_tables = 0; -int print_size = 0; -int split_output = 0; -char *preparer = PREPARER_DEFAULT; -char *publisher = PUBLISHER_DEFAULT; -char *appid = APPID_DEFAULT; -char *copyright = COPYRIGHT_DEFAULT; -char *biblio = BIBLIO_DEFAULT; -char *abstract = ABSTRACT_DEFAULT; -char *volset_id = VOLSET_ID_DEFAULT; -char *volume_id = VOLUME_ID_DEFAULT; -char *system_id = SYSTEM_ID_DEFAULT; -char *boot_catalog = BOOT_CATALOG_DEFAULT; -char *boot_image = BOOT_IMAGE_DEFAULT; -char *boot_image_embed = NULL; -int volume_set_size = 1; -int volume_sequence_number = 1; - -int omit_period = 0; /* Violates iso9660, but these are a pain */ -int transparent_compression = 0; /* So far only works with linux */ -int omit_version_number = 0; /* May violate iso9660, but noone uses vers*/ -unsigned int RR_relocation_depth = 6; /* Violates iso9660, but most systems work */ -int full_iso9660_filenames = 0; /* Used with Amiga. Disc will not work with - DOS */ -int allow_leading_dots = 0; /* DOS cannot read names with leading dots */ -int split_SL_component = 1; /* circumvent a bug in the SunOS driver */ -int split_SL_field = 1; /* circumvent a bug in the SunOS */ - -struct rcopts{ - char * tag; - char ** variable; -}; - -struct rcopts rcopt[] = { - {"PREP", &preparer}, - {"PUBL", &publisher}, - {"APPI", &appid}, - {"COPY", ©right}, - {"BIBL", &biblio}, - {"ABST", &abstract}, - {"VOLS", &volset_id}, - {"VOLI", &volume_id}, - {"SYSI", &system_id}, - {NULL, NULL} -}; - -/* - * In case it isn't obvious, the option handling code was ripped off from GNU-ld. - */ -struct ld_option -{ - /* The long option information. */ - struct option opt; - /* The short option with the same meaning ('\0' if none). */ - char shortopt; - /* The name of the argument (NULL if none). */ - const char *arg; - /* The documentation string. If this is NULL, this is a synonym for - the previous option. */ - const char *doc; - enum - { - /* Use one dash before long option name. */ - ONE_DASH, - /* Use two dashes before long option name. */ - TWO_DASHES, - /* Don't mention this option in --help output. */ - NO_HELP - } control; -}; - -/* Codes used for the long options with no short synonyms. 150 isn't - special; it's just an arbitrary non-ASCII char value. */ -#define OPTION_HELP 150 -#define OPTION_QUIET 151 -#define OPTION_NOSPLIT_SL_COMPONENT 152 -#define OPTION_NOSPLIT_SL_FIELD 153 -#define OPTION_PRINT_SIZE 154 -#define OPTION_SPLIT_OUTPUT 155 -#define OPTION_ABSTRACT 156 -#define OPTION_BIBLIO 157 -#define OPTION_COPYRIGHT 158 -#define OPTION_SYSID 159 -#define OPTION_VOLSET 160 -#define OPTION_VOLSET_SIZE 161 -#define OPTION_VOLSET_SEQ_NUM 162 -#define OPTION_I_HIDE 163 -#define OPTION_J_HIDE 164 -#define OPTION_LOG_FILE 165 - -#define OPTION_CREAT_DATE 166 -#define OPTION_MODIF_DATE 167 -#define OPTION_EXPIR_DATE 168 -#define OPTION_EFFEC_DATE 169 - -#define OPTION_BOOT_INFO_TABLE 170 -#define OPTION_NO_EMUL_BOOT 171 -#define OPTION_ELTORITO_EMUL_FLOPPY 172 - -#define OPTION_VERSION 173 - -#define OPTION_PROTECTIVE_MSDOS_LABEL 174 - -static const struct ld_option ld_options[] = -{ - { {"all-files", no_argument, NULL, 'a'}, - 'a', NULL, N_("Process all files (don't skip backup files)"), ONE_DASH }, - { {"abstract", required_argument, NULL, OPTION_ABSTRACT}, - '\0', N_("FILE"), N_("Set Abstract filename"), ONE_DASH }, - { {"appid", required_argument, NULL, 'A'}, - 'A', N_("ID"), N_("Set Application ID"), ONE_DASH }, - { {"biblio", required_argument, NULL, OPTION_BIBLIO}, - '\0', N_("FILE"), N_("Set Bibliographic filename"), ONE_DASH }, - { {"copyright", required_argument, NULL, OPTION_COPYRIGHT}, - '\0', N_("FILE"), N_("Set Copyright filename"), ONE_DASH }, - { {"embedded-boot", required_argument, NULL, 'G'}, - 'G', N_("FILE"), N_("Set embedded boot image name"), TWO_DASHES }, - { {"protective-msdos-label", no_argument, NULL, OPTION_PROTECTIVE_MSDOS_LABEL }, - '\0', NULL, N_("Patch a protective DOS-style label in the image"), TWO_DASHES }, - { {"eltorito-boot", required_argument, NULL, 'b'}, - 'b', N_("FILE"), N_("Set El Torito boot image name"), ONE_DASH }, - { {"eltorito-catalog", required_argument, NULL, 'c'}, - 'c', N_("FILE"), N_("Set El Torito boot catalog name"), ONE_DASH }, - { {"boot-info-table", no_argument, NULL, OPTION_BOOT_INFO_TABLE }, - '\0', NULL, N_("Patch Boot Info Table in El Torito boot image"), ONE_DASH }, - { {"no-emul-boot", no_argument, NULL, OPTION_NO_EMUL_BOOT }, - '\0', NULL, N_("Dummy option for backward compatibility"), ONE_DASH }, - { {"eltorito-emul-floppy", no_argument, NULL, OPTION_ELTORITO_EMUL_FLOPPY }, - '\0', NULL, N_("Enable floppy drive emulation for El Torito"), TWO_DASHES }, - { {"cdwrite-params", required_argument, NULL, 'C'}, - 'C', N_("PARAMS"), N_("Magic parameters from cdrecord"), ONE_DASH }, - { {"omit-period", no_argument, NULL, 'd'}, - 'd', NULL, N_("Omit trailing periods from filenames"), ONE_DASH }, - { {"disable-deep-relocation", no_argument, NULL, 'D'}, - 'D', NULL, N_("Disable deep directory relocation"), ONE_DASH }, - { {"follow-links", no_argument, NULL, 'f'}, - 'f', NULL, N_("Follow symbolic links"), ONE_DASH }, - { {"help", no_argument, NULL, OPTION_HELP}, - '\0', NULL, N_("Print option help"), ONE_DASH }, - { {"help", no_argument, NULL, OPTION_HELP}, - '\0', NULL, N_("Print option help"), TWO_DASHES }, - { {"version", no_argument, NULL, OPTION_VERSION}, - '\0', NULL, N_("Print version information and exit"), TWO_DASHES }, - { {"hide", required_argument, NULL, OPTION_I_HIDE}, - '\0', N_("GLOBFILE"), N_("Hide ISO9660/RR file"), ONE_DASH }, - { {"hide-joliet", required_argument, NULL, OPTION_J_HIDE}, - '\0', N_("GLOBFILE"), N_("Hide Joliet file"), ONE_DASH }, - { {NULL, required_argument, NULL, 'i'}, - 'i', N_("ADD_FILES"), N_("No longer supported"), TWO_DASHES }, - { {"joliet", no_argument, NULL, 'J'}, - 'J', NULL, N_("Generate Joliet directory information"), ONE_DASH }, - { {"full-iso9660-filenames", no_argument, NULL, 'l'}, - 'l', NULL, N_("Allow full 32 character filenames for iso9660 names"), ONE_DASH }, - { {"allow-leading-dots", no_argument, NULL, 'L'}, - 'L', NULL, N_("Allow iso9660 filenames to start with '.'"), ONE_DASH }, - { {"log-file", required_argument, NULL, OPTION_LOG_FILE}, - '\0', N_("LOG_FILE"), N_("Re-direct messages to LOG_FILE"), ONE_DASH }, - { {"exclude", required_argument, NULL, 'm'}, - 'm', N_("GLOBFILE"), N_("Exclude file name"), ONE_DASH }, - { {"prev-session", required_argument, NULL, 'M'}, - 'M', N_("FILE"), N_("Set path to previous session to merge"), ONE_DASH }, - { {"omit-version-number", no_argument, NULL, 'N'}, - 'N', NULL, N_("Omit version number from iso9660 filename"), ONE_DASH }, - { {"no-split-symlink-components", no_argument, NULL, 0}, - 0, NULL, N_("Inhibit splitting symlink components"), ONE_DASH }, - { {"no-split-symlink-fields", no_argument, NULL, 0}, - 0, NULL, N_("Inhibit splitting symlink fields"), ONE_DASH }, - { {"output", required_argument, NULL, 'o'}, - 'o', N_("FILE"), N_("Set output file name"), ONE_DASH }, - { {"preparer", required_argument, NULL, 'p'}, - 'p', N_("PREP"), N_("Set Volume preparer"), ONE_DASH }, - { {"print-size", no_argument, NULL, OPTION_PRINT_SIZE}, - '\0', NULL, N_("Print estimated filesystem size and exit"), ONE_DASH }, - { {"publisher", required_argument, NULL, 'P'}, - 'P', N_("PUB"), N_("Set Volume publisher"), ONE_DASH }, - { {"quiet", no_argument, NULL, OPTION_QUIET}, - '\0', NULL, N_("Run quietly"), ONE_DASH }, - { {"rational-rock", no_argument, NULL, 'r'}, - 'r', NULL, N_("Generate rationalized Rock Ridge directory information"), ONE_DASH }, - { {"rock", no_argument, NULL, 'R'}, - 'R', NULL, N_("Generate Rock Ridge directory information"), ONE_DASH }, - { {"split-output", no_argument, NULL, OPTION_SPLIT_OUTPUT}, - '\0', NULL, N_("Split output into files of approx. 1GB size"), ONE_DASH }, - { {"sysid", required_argument, NULL, OPTION_SYSID}, - '\0', N_("ID"), N_("Set System ID"), ONE_DASH }, - { {"translation-table", no_argument, NULL, 'T'}, - 'T', NULL, N_("Generate translation tables for systems that don't understand long filenames"), ONE_DASH }, - { {"verbose", no_argument, NULL, 'v'}, - 'v', NULL, N_("Verbose"), ONE_DASH }, - { {"volid", required_argument, NULL, 'V'}, - 'V', N_("ID"), N_("Set Volume ID"), ONE_DASH }, - { {"volset", required_argument, NULL, OPTION_VOLSET}, - '\0', N_("ID"), N_("Set Volume set ID"), ONE_DASH }, - { {"volset-size", required_argument, NULL, OPTION_VOLSET_SIZE}, - '\0', "#", N_("Set Volume set size"), ONE_DASH }, - { {"volset-seqno", required_argument, NULL, OPTION_VOLSET_SEQ_NUM}, - '\0', "#", N_("Set Volume set sequence number"), ONE_DASH }, - { {"old-exclude", required_argument, NULL, 'x'}, - 'x', N_("FILE"), N_("Exclude file name (deprecated)"), ONE_DASH }, -#ifdef ERIC_neverdef - { {"transparent-compression", no_argument, NULL, 'z'}, - 'z', NULL, "Enable transparent compression of files", ONE_DASH }, -#endif - { {"creation-date", required_argument, NULL, OPTION_CREAT_DATE }, - '\0', NULL, N_("Override creation date"), TWO_DASHES }, - { {"modification-date", required_argument, NULL, OPTION_MODIF_DATE }, - '\0', NULL, N_("Override modification date"), TWO_DASHES }, - { {"expiration-date", required_argument, NULL, OPTION_EXPIR_DATE }, - '\0', NULL, N_("Override expiration date"), TWO_DASHES }, - { {"effective-date", required_argument, NULL, OPTION_EFFEC_DATE }, - '\0', NULL, N_("Override effective date"), TWO_DASHES }, -}; - -#define OPTION_COUNT (sizeof ld_options / sizeof ld_options[0]) - -#if defined(ultrix) || defined(_AUX_SOURCE) -char *strdup(s) -char *s;{char *c;if(c=(char *)malloc(strlen(s)+1))strcpy(c,s);return c;} -#endif - - void read_rcfile __PR((char * appname)); - void usage __PR((void)); -static void hide_reloc_dir __PR((void)); - -void FDECL1(read_rcfile, char *, appname) -{ - FILE * rcfile; - struct rcopts * rco; - char * pnt, *pnt1; - char linebuffer[256]; - static char rcfn[] = ".mkisofsrc"; - char filename[1000]; - int linum; - - strcpy(filename, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - - if (!rcfile) - { - pnt = getenv("MKISOFSRC"); - if (pnt && strlen(pnt) <= sizeof(filename)) - { - strcpy(filename, pnt); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - - if (!rcfile) - { - pnt = getenv("HOME"); - if (pnt && strlen(pnt) + strlen(rcfn) + 2 <= sizeof(filename)) - { - strcpy(filename, pnt); - strcat(filename, "/"); - strcat(filename, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - if (!rcfile && strlen(appname)+sizeof(rcfn)+2 <= sizeof(filename)) - { - strcpy(filename, appname); - pnt = strrchr(filename, '/'); - if (pnt) - { - strcpy(pnt + 1, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - if (!rcfile) - return; - if ( verbose > 0 ) - { - fprintf (stderr, _("Using \"%s\"\n"), filename); - } - - /* OK, we got it. Now read in the lines and parse them */ - linum = 0; - while (fgets(linebuffer, sizeof(linebuffer), rcfile)) - { - char *name; - char *name_end; - ++linum; - /* skip any leading white space */ - pnt = linebuffer; - while (*pnt == ' ' || *pnt == '\t') - ++pnt; - /* If we are looking at a # character, this line is a comment. */ - if (*pnt == '#') - continue; - /* The name should begin in the left margin. Make sure it is in - upper case. Stop when we see white space or a comment. */ - name = pnt; - while (*pnt && isalpha((unsigned char)*pnt)) - { - if(islower((unsigned char)*pnt)) - *pnt = toupper((unsigned char)*pnt); - pnt++; - } - if (name == pnt) - { - fprintf(stderr, _("%s:%d: name required\n"), filename, linum); - continue; - } - name_end = pnt; - /* Skip past white space after the name */ - while (*pnt == ' ' || *pnt == '\t') - pnt++; - /* silently ignore errors in the rc file. */ - if (*pnt != '=') - { - fprintf (stderr, _("%s:%d: equals sign required\n"), filename, linum); - continue; - } - /* Skip pas the = sign, and any white space following it */ - pnt++; /* Skip past '=' sign */ - while (*pnt == ' ' || *pnt == '\t') - pnt++; - - /* now it is safe to NUL terminate the name */ - - *name_end = 0; - - /* Now get rid of trailing newline */ - - pnt1 = pnt; - while (*pnt1) - { - if (*pnt1 == '\n') - { - *pnt1 = 0; - break; - } - pnt1++; - }; - /* OK, now figure out which option we have */ - for(rco = rcopt; rco->tag; rco++) { - if(strcmp(rco->tag, name) == 0) - { - *rco->variable = strdup(pnt); - break; - }; - } - if (rco->tag == NULL) - { - fprintf (stderr, _("%s:%d: field name \"%s\" unknown\n"), filename, linum, - name); - } - } - if (ferror(rcfile)) - perror(filename); - fclose(rcfile); -} - -char * path_table_l = NULL; -char * path_table_m = NULL; - -char * jpath_table_l = NULL; -char * jpath_table_m = NULL; - -int goof = 0; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -void usage(){ - unsigned int i; -/* const char **targets, **pp;*/ - - printf (_("Usage: %s [options] file...\n"), program_name); - - printf (_("Options:\n")); - for (i = 0; i < OPTION_COUNT; i++) - { - if (ld_options[i].doc != NULL) - { - int comma; - int len; - unsigned int j; - const char *arg; - - printf (" "); - - comma = FALSE; - len = 2; - - j = i; - do - { - if (ld_options[j].shortopt != '\0' - && ld_options[j].control != NO_HELP) - { - printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt); - len += (comma ? 2 : 0) + 2; - if (ld_options[j].arg != NULL) - { - if (ld_options[j].opt.has_arg != optional_argument) - { - putchar (' '); - ++len; - } - arg = gettext (ld_options[j].arg); - printf ("%s", arg); - len += strlen (arg); - } - comma = TRUE; - } - ++j; - } - while (j < OPTION_COUNT && ld_options[j].doc == NULL); - - j = i; - do - { - if (ld_options[j].opt.name != NULL - && ld_options[j].control != NO_HELP) - { - printf ("%s-%s%s", - comma ? ", " : "", - ld_options[j].control == TWO_DASHES ? "-" : "", - ld_options[j].opt.name); - len += ((comma ? 2 : 0) - + 1 - + (ld_options[j].control == TWO_DASHES ? 1 : 0) - + strlen (ld_options[j].opt.name)); - if (ld_options[j].arg != NULL) - { - arg = gettext (ld_options[j].arg); - printf (" %s", arg); - len += 1 + strlen (arg); - } - comma = TRUE; - } - ++j; - } - while (j < OPTION_COUNT && ld_options[j].doc == NULL); - - if (len >= 30) - { - printf ("\n"); - len = 0; - } - - for (; len < 30; len++) - putchar (' '); - - printf ("%s\n", gettext (ld_options[i].doc)); - } - } - exit(1); -} - - -/* - * Fill in date in the iso9660 format - * - * The standards state that the timezone offset is in multiples of 15 - * minutes, and is what you add to GMT to get the localtime. The U.S. - * is always at a negative offset, from -5h to -8h (can vary a little - * with DST, I guess). The Linux iso9660 filesystem has had the sign - * of this wrong for ages (mkisofs had it wrong too for the longest time). - */ -int FDECL2(iso9660_date,char *, result, time_t, crtime){ - struct tm *local; - local = localtime(&crtime); - result[0] = local->tm_year; - result[1] = local->tm_mon + 1; - result[2] = local->tm_mday; - result[3] = local->tm_hour; - result[4] = local->tm_min; - result[5] = local->tm_sec; - - /* - * Must recalculate proper timezone offset each time, - * as some files use daylight savings time and some don't... - */ - result[6] = local->tm_yday; /* save yday 'cause gmtime zaps it */ - local = gmtime(&crtime); - local->tm_year -= result[0]; - local->tm_yday -= result[6]; - local->tm_hour -= result[3]; - local->tm_min -= result[4]; - if (local->tm_year < 0) - { - local->tm_yday = -1; - } - else - { - if (local->tm_year > 0) local->tm_yday = 1; - } - - result[6] = -(local->tm_min + 60*(local->tm_hour + 24*local->tm_yday)) / 15; - - return 0; -} - -/* hide "./rr_moved" if all its contents are hidden */ -static void -hide_reloc_dir() -{ - struct directory_entry * s_entry; - - for (s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) { - if(strcmp(s_entry->name,".")==0 || strcmp(s_entry->name,"..")==0) - continue; - - if((s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) - return; - } - - /* all entries are hidden, so hide this directory */ - reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; - reloc_dir->self->de_flags |= INHIBIT_ISO9660_ENTRY; -} - -extern char * cdwrite_data; - -int FDECL2(main, int, argc, char **, argv){ - struct directory_entry de; -#ifdef HAVE_SBRK - unsigned long mem_start; -#endif - struct stat statbuf; - char * scan_tree; - char * merge_image = NULL; - struct iso_directory_record * mrootp = NULL; - struct output_fragment * opnt; - int longind; - char shortopts[OPTION_COUNT * 3 + 2]; - struct option longopts[OPTION_COUNT + 1]; - int c; - char *log_file = 0; - - set_program_name (argv[0]); -#if (defined(ENABLE_NLS) && ENABLE_NLS) - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ - - if (argc < 2) - usage(); - - /* Get the defaults from the .mkisofsrc file */ - read_rcfile(argv[0]); - - outfile = NULL; - - /* - * Copy long option initialization from GNU-ld. - */ - /* Starting the short option string with '-' is for programs that - expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. */ - { - unsigned int i; - int is, il; - shortopts[0] = '-'; - is = 1; - il = 0; - for (i = 0; i < OPTION_COUNT; i++) - { - if (ld_options[i].shortopt != '\0') - { - shortopts[is] = ld_options[i].shortopt; - ++is; - if (ld_options[i].opt.has_arg == required_argument - || ld_options[i].opt.has_arg == optional_argument) - { - shortopts[is] = ':'; - ++is; - if (ld_options[i].opt.has_arg == optional_argument) - { - shortopts[is] = ':'; - ++is; - } - } - } - if (ld_options[i].opt.name != NULL) - { - longopts[il] = ld_options[i].opt; - ++il; - } - } - shortopts[is] = '\0'; - longopts[il].name = NULL; - } - - while ((c = getopt_long_only (argc, argv, shortopts, longopts, &longind)) != EOF) - switch (c) - { - case 1: - /* - * A filename that we take as input. - */ - optind--; - goto parse_input_files; - case 'C': - /* - * This is a temporary hack until cdwrite gets the proper hooks in - * it. - */ - cdwrite_data = optarg; - break; - case 'i': - fprintf (stderr, _("-i option no longer supported.\n")); - exit(1); - break; - case 'J': - use_Joliet++; - break; - case 'a': - all_files++; - break; - case 'b': - use_eltorito++; - boot_image = optarg; /* pathname of the boot image on cd */ - if (boot_image == NULL) - error (1, 0, _("Required boot image pathname missing")); - break; - case 'G': - use_embedded_boot = 1; - boot_image_embed = optarg; /* pathname of the boot image on host filesystem */ - if (boot_image_embed == NULL) - error (1, 0, _("Required boot image pathname missing")); - break; - case OPTION_PROTECTIVE_MSDOS_LABEL: - use_protective_msdos_label = 1; - break; - case 'c': - use_eltorito++; - boot_catalog = optarg; /* pathname of the boot image on cd */ - if (boot_catalog == NULL) - { - fprintf (stderr, _("Required boot catalog pathname missing\n")); - exit (1); - } - break; - case OPTION_BOOT_INFO_TABLE: - use_boot_info_table = 1; - break; - case OPTION_NO_EMUL_BOOT: - fprintf (stderr, _("Ignoring -no-emul-boot (no-emulation is the default behaviour)\n")); - break; - case OPTION_ELTORITO_EMUL_FLOPPY: - use_eltorito_emul_floppy = 1; - break; - case OPTION_ABSTRACT: - abstract = optarg; - if(strlen(abstract) > 37) - { - fprintf (stderr, _("Abstract filename string too long\n")); - exit (1); - }; - break; - case 'A': - appid = optarg; - if(strlen(appid) > 128) - { - fprintf (stderr, _("Application-id string too long\n")); - exit (1); - }; - break; - case OPTION_BIBLIO: - biblio = optarg; - if(strlen(biblio) > 37) - { - fprintf (stderr, _("Bibliographic filename string too long\n")); - exit (1); - }; - break; - case OPTION_COPYRIGHT: - copyright = optarg; - if(strlen(copyright) > 37) - { - fprintf (stderr, _("Copyright filename string too long\n")); - exit (1); - }; - break; - case 'd': - omit_period++; - break; - case 'D': - RR_relocation_depth = 32767; - break; - case 'f': - follow_links++; - break; - case 'l': - full_iso9660_filenames++; - break; - case 'L': - allow_leading_dots++; - break; - case OPTION_LOG_FILE: - log_file = optarg; - break; - case 'M': - merge_image = optarg; - break; - case 'N': - omit_version_number++; - break; - case 'o': - outfile = optarg; - break; - case 'p': - preparer = optarg; - if(strlen(preparer) > 128) - { - fprintf (stderr, _("Preparer string too long\n")); - exit (1); - }; - break; - case OPTION_PRINT_SIZE: - print_size++; - break; - case 'P': - publisher = optarg; - if(strlen(publisher) > 128) - { - fprintf (stderr, _("Publisher string too long\n")); - exit (1); - }; - break; - case OPTION_QUIET: - verbose = 0; - break; - case 'R': - use_RockRidge++; - break; - case 'r': - rationalize++; - use_RockRidge++; - break; - case OPTION_SPLIT_OUTPUT: - split_output++; - break; - case OPTION_SYSID: - system_id = optarg; - if(strlen(system_id) > 32) - { - fprintf (stderr, _("System ID string too long\n")); - exit (1); - }; - break; - case 'T': - generate_tables++; - break; - case 'V': - volume_id = optarg; - if(strlen(volume_id) > 32) - { - fprintf (stderr, _("Volume ID string too long\n")); - exit (1); - }; - break; - case OPTION_VOLSET: - volset_id = optarg; - if(strlen(volset_id) > 128) - { - fprintf (stderr, _("Volume set ID string too long\n")); - exit (1); - }; - break; - case OPTION_VOLSET_SIZE: - volume_set_size = atoi(optarg); - break; - case OPTION_VOLSET_SEQ_NUM: - volume_sequence_number = atoi(optarg); - if (volume_sequence_number > volume_set_size) - { - fprintf (stderr, _("Volume set sequence number too big\n")); - exit (1); - } - break; - case 'v': - verbose++; - break; - case 'z': - transparent_compression++; - break; - case 'x': - case 'm': - /* - * Somehow two options to do basically the same thing got added somewhere along - * the way. The 'match' code supports limited globbing, so this is the one - * that got selected. Unfortunately the 'x' switch is probably more intuitive. - */ - add_match(optarg); - break; - case OPTION_I_HIDE: - i_add_match(optarg); - break; - case OPTION_J_HIDE: - j_add_match(optarg); - break; - case OPTION_HELP: - usage (); - exit (0); - break; - case OPTION_VERSION: - printf ("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); - exit (0); - break; - case OPTION_NOSPLIT_SL_COMPONENT: - split_SL_component = 0; - break; - case OPTION_NOSPLIT_SL_FIELD: - split_SL_field = 0; - break; - case OPTION_CREAT_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (creation_date) - free(creation_date); - creation_date = strdup(optarg); - break; - case OPTION_MODIF_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (modification_date) - free(modification_date); - modification_date = strdup(optarg); - break; - case OPTION_EXPIR_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (expiration_date) - free(expiration_date); - expiration_date = strdup(optarg); - break; - case OPTION_EFFEC_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (effective_date) - free(effective_date); - effective_date = strdup(optarg); - break; - default: - usage(); - exit(1); - } - -parse_input_files: - -#ifdef __NetBSD__ - { - int resource; - struct rlimit rlp; - if (getrlimit(RLIMIT_DATA,&rlp) == -1) - perror (_("Warning: getrlimit")); - else { - rlp.rlim_cur=33554432; - if (setrlimit(RLIMIT_DATA,&rlp) == -1) - perror (_("Warning: setrlimit")); - } - } -#endif -#ifdef HAVE_SBRK - mem_start = (unsigned long) sbrk(0); -#endif - - /* if the -hide-joliet option has been given, set the Joliet option */ - if (!use_Joliet && j_ishidden()) - use_Joliet++; - - if(verbose > 1) fprintf(stderr,"%s\n", version_string); - - if(cdwrite_data == NULL && merge_image != NULL) - { - fprintf (stderr, _("Multisession usage bug: Must specify -C if -M is used.\n")); - exit (0); - } - - if(cdwrite_data != NULL && merge_image == NULL) - { - fprintf (stderr, _("Warning: -C specified without -M: old session data will not be merged.\n")); - } - - /* The first step is to scan the directory tree, and take some notes */ - - scan_tree = argv[optind]; - - - if(!scan_tree){ - usage(); - exit(1); - }; - -#ifndef VMS - if(scan_tree[strlen(scan_tree)-1] != '/') { - scan_tree = (char *) e_malloc(strlen(argv[optind])+2); - strcpy(scan_tree, argv[optind]); - strcat(scan_tree, "/"); - }; -#endif - - if(use_RockRidge){ -#if 1 - extension_record = generate_rr_extension_record("RRIP_1991A", - "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", - "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", &extension_record_size); -#else - extension_record = generate_rr_extension_record("IEEE_P1282", - "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", - "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", &extension_record_size); -#endif - } - - if (log_file) { - FILE *lfp; - int i; - - /* open log file - test that we can open OK */ - if ((lfp = fopen(log_file, "w")) == NULL) - error (1, errno, _("can't open logfile: %s"), log_file); - fclose(lfp); - - /* redirect all stderr message to log_file */ - fprintf (stderr, _("re-directing all messages to %s\n"), log_file); - fflush(stderr); - - /* associate stderr with the log file */ - if (freopen(log_file, "w", stderr) == NULL) - error (1, errno, _("can't open logfile: %s\n"), log_file); - if(verbose > 1) { - for (i=0;iextent, 8); - } - - /* - * Create an empty root directory. If we ever scan it for real, we will fill in the - * contents. - */ - find_or_create_directory(NULL, "", &de, TRUE); - - /* - * Scan the actual directory (and any we find below it) - * for files to write out to the output image. Note - we - * take multiple source directories and keep merging them - * onto the image. - */ - while(optind < argc) - { - char * node; - struct directory * graft_dir; - struct stat st; - char * short_name; - int status; - char graft_point[1024]; - - /* - * We would like a syntax like: - * - * /tmp=/usr/tmp/xxx - * - * where the user can specify a place to graft each - * component of the tree. To do this, we may have to create - * directories along the way, of course. - * Secondly, I would like to allow the user to do something - * like: - * - * /home/baz/RMAIL=/u3/users/baz/RMAIL - * - * so that normal files could also be injected into the tree - * at an arbitrary point. - * - * The idea is that the last component of whatever is being - * entered would take the name from the last component of - * whatever the user specifies. - * - * The default will be that the file is injected at the - * root of the image tree. - */ - node = strchr(argv[optind], '='); - short_name = NULL; - - if( node != NULL ) - { - char * pnt; - char * xpnt; - - *node = '\0'; - strcpy(graft_point, argv[optind]); - *node = '='; - node++; - - graft_dir = root; - xpnt = graft_point; - if( *xpnt == PATH_SEPARATOR ) - { - xpnt++; - } - - /* - * Loop down deeper and deeper until we - * find the correct insertion spot. - */ - while(1==1) - { - pnt = strchr(xpnt, PATH_SEPARATOR); - if( pnt == NULL ) - { - if( *xpnt != '\0' ) - { - short_name = xpnt; - } - break; - } - *pnt = '\0'; - graft_dir = find_or_create_directory(graft_dir, - graft_point, - NULL, TRUE); - *pnt = PATH_SEPARATOR; - xpnt = pnt + 1; - } - } - else - { - graft_dir = root; - node = argv[optind]; - } - - /* - * Now see whether the user wants to add a regular file, - * or a directory at this point. - */ - status = stat_filter(node, &st); - if( status != 0 ) - { - /* - * This is a fatal error - the user won't be getting what - * they want if we were to proceed. - */ - error (1, 0, _("Invalid node - %s\n"), node); - } - else - { - if( S_ISDIR(st.st_mode) ) - { - if (!scan_directory_tree(graft_dir, node, &de)) - { - exit(1); - } - } - else - { - if( short_name == NULL ) - { - short_name = strrchr(node, PATH_SEPARATOR); - if( short_name == NULL || short_name < node ) - { - short_name = node; - } - else - { - short_name++; - } - } - if( !insert_file_entry(graft_dir, node, short_name) ) - { - exit(1); - } - } - } - - optind++; - } - - - /* - * Now merge in any previous sessions. This is driven on the source - * side, since we may need to create some additional directories. - */ - if( merge_image != NULL ) - { - merge_previous_session(root, mrootp); - } - - /* hide "./rr_moved" if all its contents have been hidden */ - if (reloc_dir && i_ishidden()) - hide_reloc_dir(); - - /* - * Sort the directories in the required order (by ISO9660). Also, - * choose the names for the 8.3 filesystem if required, and do - * any other post-scan work. - */ - goof += sort_tree(root); - - if( use_Joliet ) - { - goof += joliet_sort_tree(root); - } - - if (goof) - error (1, 0, _("Joliet tree sort failed.\n")); - - /* - * Fix a couple of things in the root directory so that everything - * is self consistent. - */ - root->self = root->contents; /* Fix this up so that the path - tables get done right */ - - /* - * OK, ready to write the file. Open it up, and generate the thing. - */ - if (print_size){ - discimage = fopen("/dev/null", "wb"); - if (!discimage) - error (1, errno, _("Unable to open /dev/null\n")); - } else if (outfile){ - discimage = fopen(outfile, "wb"); - if (!discimage) - error (1, errno, _("Unable to open disc image file\n")); - } else { - discimage = stdout; - -#if defined(__CYGWIN32__) - setmode(fileno(stdout), O_BINARY); -#endif - } - - /* Now assign addresses on the disc for the path table. */ - - path_blocks = (path_table_size + (SECTOR_SIZE - 1)) >> 11; - if (path_blocks & 1) path_blocks++; - - jpath_blocks = (jpath_table_size + (SECTOR_SIZE - 1)) >> 11; - if (jpath_blocks & 1) jpath_blocks++; - - /* - * Start to set up the linked list that we use to track the - * contents of the disc. - */ - outputlist_insert(&padblock_desc); - - /* - * PVD for disc. - */ - outputlist_insert(&voldesc_desc); - - /* - * SVD for El Torito. MUST be immediately after the PVD! - */ - if( use_eltorito) - { - outputlist_insert(&torito_desc); - } - - /* - * SVD for Joliet. - */ - if( use_Joliet) - { - outputlist_insert(&joliet_desc); - } - - /* - * Finally the last volume desctiptor. - */ - outputlist_insert(&end_vol); - - - outputlist_insert(&pathtable_desc); - if( use_Joliet) - { - outputlist_insert(&jpathtable_desc); - } - - outputlist_insert(&dirtree_desc); - if( use_Joliet) - { - outputlist_insert(&jdirtree_desc); - } - - outputlist_insert(&dirtree_clean); - - if(extension_record) - { - outputlist_insert(&extension_desc); - } - - outputlist_insert(&files_desc); - - /* - * Allow room for the various headers we will be writing. There - * will always be a primary and an end volume descriptor. - */ - last_extent = session_start; - - /* - * Calculate the size of all of the components of the disc, and assign - * extent numbers. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_size != NULL ) - { - (*opnt->of_size)(last_extent); - } - } - - /* - * Generate the contents of any of the sections that we want to generate. - * Not all of the fragments will do anything here - most will generate the - * data on the fly when we get to the write pass. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_generate != NULL ) - { - (*opnt->of_generate)(); - } - } - - if( in_image != NULL ) - { - fclose(in_image); - } - - /* - * Now go through the list of fragments and write the data that corresponds to - * each one. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_write != NULL ) - { - (*opnt->of_write)(discimage); - } - } - - if( verbose > 0 ) - { -#ifdef HAVE_SBRK - fprintf (stderr, _("Max brk space used %x\n"), - (unsigned int)(((unsigned long)sbrk(0)) - mem_start)); -#endif - fprintf (stderr, _("%llu extents written (%llu MiB)\n"), last_extent, last_extent >> 9); - } - -#ifdef VMS - return 1; -#else - return 0; -#endif -} - -void * -FDECL1(e_malloc, size_t, size) -{ - void* pt = 0; - if( (size > 0) && ((pt = malloc (size)) == NULL)) - error (1, errno, "malloc"); -return pt; -} diff --git a/util/mkisofs/mkisofs.h b/util/mkisofs/mkisofs.h deleted file mode 100644 index b699516e9..000000000 --- a/util/mkisofs/mkisofs.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Header file mkisofs.h - assorted structure definitions and typecasts. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 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, 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 . - */ - -/* - * $Id: mkisofs.h,v 1.20 1999/03/02 04:16:41 eric Exp $ - */ - -#include -#include -#include -#include - -#if (defined(ENABLE_NLS) && ENABLE_NLS) - -# include -# include - -#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */ - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ - -#define _(str) gettext(str) -#define N_(str) str - -/* This symbol is used to indicate that we do not have things like - symlinks, devices, and so forth available. Just files and dirs */ - -#ifdef VMS -#define NON_UNIXFS -#endif - -#ifdef DJGPP -#define NON_UNIXFS -#endif - -#ifdef VMS -#include -#define dirent direct -#endif - -#ifdef _WIN32 -#define NON_UNIXFS -#endif /* _WIN32 */ - -#ifndef S_IROTH -#define S_IROTH 0 -#endif - -#ifndef S_IRGRP -#define S_IRGRP 0 -#endif - -#ifndef HAVE_GETUID -static inline int -getuid () -{ - return 0; -} -#endif - -#ifndef HAVE_GETGID -static inline int -getgid () -{ - return 0; -} -#endif - -#ifndef HAVE_LSTAT -static inline int -lstat (const char *filename, struct stat *buf) -{ - return stat (filename, buf); -} -#endif - -#include -#include -#include - -#if defined(HAVE_DIRENT_H) -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if defined(HAVE_SYS_NDIR_H) -# include -# endif -# if defined(HAVE_SYS_DIR_H) -# include -# endif -# if defined(HAVE_NDIR_H) -# include -# endif -#endif - -#if defined(HAVE_STRING_H) -#include -#else -#if defined(HAVE_STRINGS_H) -#include -#endif -#endif - -#ifdef ultrix -extern char *strdup(); -#endif - -#ifdef __STDC__ -#define DECL(NAME,ARGS) NAME ARGS -#define FDECL1(NAME,TYPE0, ARG0) \ - NAME(TYPE0 ARG0) -#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) \ - NAME(TYPE0 ARG0, TYPE1 ARG1) -#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2) -#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3) -#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4) -#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4, TYPE5 ARG5) -#else -#define DECL(NAME,ARGS) NAME() -#define FDECL1(NAME,TYPE0, ARG0) NAME(ARG0) TYPE0 ARG0; -#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) NAME(ARG0, ARG1) TYPE0 ARG0; TYPE1 ARG1; -#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \ - NAME(ARG0, ARG1, ARG2) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; -#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; -#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; -#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; TYPE5 ARG5; -#define const -#endif - - -#ifdef __SVR4 -#include -#else -extern int optind; -extern char *optarg; -/* extern int getopt (int __argc, char **__argv, char *__optstring); */ -#endif - -#include "iso9660.h" -#include "defaults.h" - -struct directory_entry{ - struct directory_entry * next; - struct directory_entry * jnext; - struct iso_directory_record isorec; - uint64_t starting_block; - uint64_t size; - unsigned short priority; - unsigned char jreclen; /* Joliet record len */ - char * name; - char * table; - char * whole_name; - struct directory * filedir; - struct directory_entry * parent_rec; - unsigned int de_flags; - ino_t inode; /* Used in the hash table */ - dev_t dev; /* Used in the hash table */ - unsigned char * rr_attributes; - unsigned int rr_attr_size; - unsigned int total_rr_attr_size; - unsigned int got_rr_name; -}; - -struct file_hash{ - struct file_hash * next; - ino_t inode; /* Used in the hash table */ - dev_t dev; /* Used in the hash table */ - unsigned int starting_block; - unsigned int size; -}; - - -/* - * This structure is used to control the output of fragments to the cdrom - * image. Everything that will be written to the output image will eventually - * go through this structure. There are two pieces - first is the sizing where - * we establish extent numbers for everything, and the second is when we actually - * generate the contents and write it to the output image. - * - * This makes it trivial to extend mkisofs to write special things in the image. - * All you need to do is hook an additional structure in the list, and the rest - * works like magic. - * - * The three passes each do the following: - * - * The 'size' pass determines the size of each component and assigns the extent number - * for that component. - * - * The 'generate' pass will adjust the contents and pointers as required now that extent - * numbers are assigned. In some cases, the contents of the record are also generated. - * - * The 'write' pass actually writes the data to the disc. - */ -struct output_fragment -{ - struct output_fragment * of_next; -#ifdef __STDC__ - int (*of_size)(int); - int (*of_generate)(void); - int (*of_write)(FILE *); -#else - int (*of_size)(); - int (*of_generate)(); - int (*of_write)(); -#endif -}; - -extern struct output_fragment * out_list; -extern struct output_fragment * out_tail; - -extern struct output_fragment padblock_desc; -extern struct output_fragment voldesc_desc; -extern struct output_fragment joliet_desc; -extern struct output_fragment torito_desc; -extern struct output_fragment end_vol; -extern struct output_fragment pathtable_desc; -extern struct output_fragment jpathtable_desc; -extern struct output_fragment dirtree_desc; -extern struct output_fragment dirtree_clean; -extern struct output_fragment jdirtree_desc; -extern struct output_fragment extension_desc; -extern struct output_fragment files_desc; - -/* - * This structure describes one complete directory. It has pointers - * to other directories in the overall tree so that it is clear where - * this directory lives in the tree, and it also must contain pointers - * to the contents of the directory. Note that subdirectories of this - * directory exist twice in this stucture. Once in the subdir chain, - * and again in the contents chain. - */ -struct directory{ - struct directory * next; /* Next directory at same level as this one */ - struct directory * subdir; /* First subdirectory in this directory */ - struct directory * parent; - struct directory_entry * contents; - struct directory_entry * jcontents; - struct directory_entry * self; - char * whole_name; /* Entire path */ - char * de_name; /* Entire path */ - unsigned int ce_bytes; /* Number of bytes of CE entries reqd for this dir */ - unsigned int depth; - unsigned int size; - unsigned int extent; - unsigned int jsize; - unsigned int jextent; - unsigned short path_index; - unsigned short jpath_index; - unsigned short dir_flags; - unsigned short dir_nlink; -}; - -extern int goof; -extern struct directory * root; -extern struct directory * reloc_dir; -extern uint64_t next_extent; -extern uint64_t last_extent; -extern uint64_t last_extent_written; -extern uint64_t session_start; - -extern unsigned int path_table_size; -extern unsigned int path_table[4]; -extern unsigned int path_blocks; -extern char * path_table_l; -extern char * path_table_m; - -extern unsigned int jpath_table_size; -extern unsigned int jpath_table[4]; -extern unsigned int jpath_blocks; -extern char * jpath_table_l; -extern char * jpath_table_m; - -extern struct iso_directory_record root_record; -extern struct iso_directory_record jroot_record; - -extern int use_eltorito; -extern int use_embedded_boot; -extern int use_protective_msdos_label; -extern int use_eltorito_emul_floppy; -extern int use_boot_info_table; -extern int use_RockRidge; -extern int use_Joliet; -extern int rationalize; -extern int follow_links; -extern int verbose; -extern int all_files; -extern int generate_tables; -extern int print_size; -extern int split_output; -extern int omit_period; -extern int omit_version_number; -extern int transparent_compression; -extern unsigned int RR_relocation_depth; -extern int full_iso9660_filenames; -extern int split_SL_component; -extern int split_SL_field; - -/* tree.c */ -extern int DECL(stat_filter, (char *, struct stat *)); -extern int DECL(lstat_filter, (char *, struct stat *)); -extern int DECL(sort_tree,(struct directory *)); -extern struct directory * - DECL(find_or_create_directory,(struct directory *, const char *, - struct directory_entry * self, int)); -extern void DECL (finish_cl_pl_entries, (void)); -extern int DECL(scan_directory_tree,(struct directory * this_dir, - char * path, - struct directory_entry * self)); -extern int DECL(insert_file_entry,(struct directory *, char *, - char *)); - -extern void DECL(generate_iso9660_directories,(struct directory *, FILE*)); -extern void DECL(dump_tree,(struct directory * node)); -extern struct directory_entry * DECL(search_tree_file, (struct - directory * node,char * filename)); -extern void DECL(update_nlink_field,(struct directory * node)); -extern void DECL (init_fstatbuf, (void)); -extern struct stat root_statbuf; - -/* eltorito.c */ -extern void DECL(init_boot_catalog, (const char * path )); -extern void DECL(get_torito_desc, (struct eltorito_boot_descriptor * path )); - -/* write.c */ -extern int DECL(get_731,(char *)); -extern int DECL(get_733,(char *)); -extern int DECL(isonum_733,(unsigned char *)); -extern void DECL(set_723,(char *, unsigned int)); -extern void DECL(set_731,(char *, unsigned int)); -extern void DECL(set_721,(char *, unsigned int)); -extern void DECL(set_733,(char *, unsigned int)); -extern int DECL(sort_directory,(struct directory_entry **)); -extern void DECL(generate_one_directory,(struct directory *, FILE*)); -extern void DECL(memcpy_max, (char *, char *, int)); -extern int DECL(oneblock_size, (int starting_extent)); -extern struct iso_primary_descriptor vol_desc; -extern void DECL(xfwrite, (void * buffer, uint64_t count, uint64_t size, FILE * file)); -extern void DECL(set_732, (char * pnt, unsigned int i)); -extern void DECL(set_722, (char * pnt, unsigned int i)); -extern void DECL(outputlist_insert, (struct output_fragment * frag)); - -/* - * Set by user command-line to override default date values - */ - -extern char *creation_date; -extern char *modification_date; -extern char *expiration_date; -extern char *effective_date; - -/* multi.c */ - -extern FILE * in_image; -extern struct iso_directory_record * - DECL(merge_isofs,(char * path)); - -extern int DECL(free_mdinfo, (struct directory_entry **, int len)); - -extern struct directory_entry ** - DECL(read_merging_directory,(struct iso_directory_record *, int*)); -extern void - DECL(merge_remaining_entries, (struct directory *, - struct directory_entry **, int)); -extern int - DECL(merge_previous_session, (struct directory *, - struct iso_directory_record *)); - -extern int DECL(get_session_start, (int *)); - -/* joliet.c */ -int DECL(joliet_sort_tree, (struct directory * node)); - -/* match.c */ -extern int DECL(matches, (char *)); -extern void DECL(add_match, (char *)); - -/* files.c */ -struct dirent * DECL(readdir_add_files, (char **, char *, DIR *)); - -/* */ - -extern int DECL(iso9660_file_length,(const char* name, - struct directory_entry * sresult, int flag)); -extern int DECL(iso9660_date,(char *, time_t)); -extern void DECL(add_hash,(struct directory_entry *)); -extern struct file_hash * DECL(find_hash,(dev_t, ino_t)); -extern void DECL(add_directory_hash,(dev_t, ino_t)); -extern struct file_hash * DECL(find_directory_hash,(dev_t, ino_t)); -extern void DECL (flush_file_hash, (void)); -extern int DECL(delete_file_hash,(struct directory_entry *)); -extern struct directory_entry * DECL(find_file_hash,(char *)); -extern void DECL(add_file_hash,(struct directory_entry *)); -extern int DECL(generate_rock_ridge_attributes,(char *, char *, - struct directory_entry *, - struct stat *, struct stat *, - int deep_flag)); -extern char * DECL(generate_rr_extension_record,(char * id, char * descriptor, - char * source, int * size)); - -extern int DECL(check_prev_session, (struct directory_entry **, int len, - struct directory_entry *, - struct stat *, - struct stat *, - struct directory_entry **)); - -#ifdef USE_SCG -/* scsi.c */ -#ifdef __STDC__ -extern int readsecs(int startsecno, void *buffer, int sectorcount); -extern int scsidev_open(char *path); -#else -extern int readsecs(); -extern int scsidev_open(); -#endif -#endif - -extern char * extension_record; -extern int extension_record_extent; -extern int n_data_extents; - -/* These are a few goodies that can be specified on the command line, and are - filled into the root record */ - -extern char *preparer; -extern char *publisher; -extern char *copyright; -extern char *biblio; -extern char *abstract; -extern char *appid; -extern char *volset_id; -extern char *system_id; -extern char *volume_id; -extern char *boot_catalog; -extern char *boot_image; -extern char *boot_image_embed; -extern int volume_set_size; -extern int volume_sequence_number; - -extern void * DECL(e_malloc,(size_t)); - - -#define SECTOR_SIZE (2048) -#define ROUND_UP(X) ((X + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) - -#define NEED_RE 1 -#define NEED_PL 2 -#define NEED_CL 4 -#define NEED_CE 8 -#define NEED_SP 16 - -#define PREV_SESS_DEV (sizeof(dev_t) >= 4 ? 0x7ffffffd : 0x7ffd) -#define TABLE_INODE (sizeof(ino_t) >= 4 ? 0x7ffffffe : 0x7ffe) -#define UNCACHED_INODE (sizeof(ino_t) >= 4 ? 0x7fffffff : 0x7fff) -#define UNCACHED_DEVICE (sizeof(dev_t) >= 4 ? 0x7fffffff : 0x7fff) - -#ifdef VMS -#define STAT_INODE(X) (X.st_ino[0]) -#define PATH_SEPARATOR ']' -#define SPATH_SEPARATOR "" -#else -#define STAT_INODE(X) (X.st_ino) -#define PATH_SEPARATOR '/' -#define SPATH_SEPARATOR "/" -#endif - -/* - * When using multi-session, indicates that we can reuse the - * TRANS.TBL information for this directory entry. If this flag - * is set for all entries in a directory, it means we can just - * reuse the TRANS.TBL and not generate a new one. - */ -#define SAFE_TO_REUSE_TABLE_ENTRY 0x01 -#define DIR_HAS_DOT 0x02 -#define DIR_HAS_DOTDOT 0x04 -#define INHIBIT_JOLIET_ENTRY 0x08 -#define INHIBIT_RR_ENTRY 0x10 -#define RELOCATED_DIRECTORY 0x20 -#define INHIBIT_ISO9660_ENTRY 0x40 - -/* - * Volume sequence number to use in all of the iso directory records. - */ -#define DEF_VSN 1 - -/* - * Make sure we have a definition for this. If not, take a very conservative - * guess. From what I can tell SunOS is the only one with this trouble. - */ -#ifndef NAME_MAX -#ifdef FILENAME_MAX -#define NAME_MAX FILENAME_MAX -#else -#define NAME_MAX 128 -#endif -#endif diff --git a/util/mkisofs/msdos_partition.h b/util/mkisofs/msdos_partition.h deleted file mode 100644 index 13985f7bb..000000000 --- a/util/mkisofs/msdos_partition.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 MSDOS_PARTITION_H -#define MSDOS_PARTITION_H 1 - -#include - -/* The signature. */ -#define MSDOS_PARTITION_SIGNATURE ((0xaa << 8) | 0x55) - -/* This is not a flag actually, but used as if it were a flag. */ -#define MSDOS_PARTITION_TYPE_HIDDEN_FLAG 0x10 - -/* The partition entry. */ -struct msdos_partition_entry -{ - /* If active, 0x80, otherwise, 0x00. */ - uint8_t flag; - - /* The head of the start. */ - 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. */ - uint8_t start_sector; - - /* (C & 0xFF) where C is the cylinder of the start. */ - uint8_t start_cylinder; - - /* The partition type. */ - uint8_t type; - - /* The end versions of start_head, start_sector and start_cylinder, - respectively. */ - uint8_t end_head; - uint8_t end_sector; - uint8_t end_cylinder; - - /* The start sector. Note that this is counted from zero. */ - uint32_t start; - - /* The length in sector units. */ - uint32_t length; -} __attribute__ ((packed)); - -/* The structure of MBR. */ -struct msdos_partition_mbr -{ - /* The code area (actually, including BPB). */ - uint8_t code[446]; - - /* Four partition entries. */ - struct msdos_partition_entry entries[4]; - - /* The signature 0xaa55. */ - uint16_t signature; -} __attribute__ ((packed)); - -#endif diff --git a/util/mkisofs/multi.c b/util/mkisofs/multi.c deleted file mode 100644 index d92f14530..000000000 --- a/util/mkisofs/multi.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* - * File multi.c - scan existing iso9660 image and merge into - * iso9660 filesystem. Used for multisession support. - * - * Written by Eric Youngdale (1996). - * - * Copyright (C) 2009 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, 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 "config.h" - -#ifndef VMS - -#ifdef HAVE_UNISTD_H -#include -#endif - -#else -#include -#include -#include "vms.h" -extern char * strdup(const char *); -#endif - -#include "mkisofs.h" -#include "iso9660.h" - -#define TF_CREATE 1 -#define TF_MODIFY 2 -#define TF_ACCESS 4 -#define TF_ATTRIBUTES 8 - -static int isonum_711 __PR((unsigned char * p)); -static int isonum_721 __PR((unsigned char * p)); -static int isonum_723 __PR((unsigned char * p)); -static int isonum_731 __PR((unsigned char * p)); - -static int DECL(merge_old_directory_into_tree, (struct directory_entry *, - struct directory *)); - -#ifdef __STDC__ -static int -isonum_711 (unsigned char * p) -#else -static int -isonum_711 (p) - unsigned char * p; -#endif -{ - return (*p & 0xff); -} - -#ifdef __STDC__ -static int -isonum_721 (unsigned char * p) -#else -static int -isonum_721 (p) - unsigned char * p; -#endif -{ - return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); -} - -#ifdef __STDC__ -static int -isonum_723 (unsigned char * p) -#else -static int -isonum_723 (p) - unsigned char * p; -#endif -{ -#if 0 - if (p[0] != p[3] || p[1] != p[2]) { - fprintf (stderr, "invalid format 7.2.3 number\n"); - exit (1); - } -#endif - return (isonum_721 (p)); -} - -#ifdef __STDC__ -static int -isonum_731 (unsigned char * p) -#else -static int -isonum_731 (p) - unsigned char * p; -#endif -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -#ifdef __STDC__ -int -isonum_733 (unsigned char * p) -#else -int -isonum_733 (p) - unsigned char * p; -#endif -{ - return (isonum_731 (p)); -} - -FILE * in_image = NULL; - -#ifndef USE_SCG -/* - * Don't define readsecs if mkisofs is linked with - * the SCSI library. - * readsecs() will be implemented as SCSI command in this case. - * - * Use global var in_image directly in readsecs() - * the SCSI equivalent will not use a FILE* for I/O. - * - * The main point of this pointless abstraction is that Solaris won't let - * you read 2K sectors from the cdrom driver. The fact that 99.9% of the - * discs out there have a 2K sectorsize doesn't seem to matter that much. - * Anyways, this allows the use of a scsi-generics type of interface on - * Solaris. - */ -#ifdef __STDC__ -static int -readsecs(int startsecno, void *buffer, int sectorcount) -#else -static int -readsecs(startsecno, buffer, sectorcount) - int startsecno; - void *buffer; - int sectorcount; -#endif -{ - int f = fileno(in_image); - - if (lseek(f, (off_t)startsecno * SECTOR_SIZE, 0) == (off_t)-1) - error (10, errno, _("Seek error on old image\n")); - return (read(f, buffer, sectorcount * SECTOR_SIZE)); -} -#endif - -/* - * Parse the RR attributes so we can find the file name. - */ -static int -FDECL3(parse_rr, unsigned char *, pnt, int, len, struct directory_entry *,dpnt) -{ - int cont_extent, cont_offset, cont_size; - char name_buf[256]; - - cont_extent = cont_offset = cont_size = 0; - - while(len >= 4){ - if(pnt[3] != 1) { - fprintf (stderr, _("**Bad RR version attribute")); - return -1; - }; - if(strncmp((char *) pnt, "NM", 2) == 0) { - strncpy(name_buf, (char *) pnt+5, pnt[2] - 5); - name_buf[pnt[2] - 5] = 0; - dpnt->name = strdup(name_buf); - dpnt->got_rr_name = 1; - return 0; - } - - if(strncmp((char *) pnt, "CE", 2) == 0) { - cont_extent = isonum_733(pnt+4); - cont_offset = isonum_733(pnt+12); - cont_size = isonum_733(pnt+20); - }; - - len -= pnt[2]; - pnt += pnt[2]; - if(len <= 3 && cont_extent) { - unsigned char sector[SECTOR_SIZE]; - readsecs(cont_extent, sector, 1); - parse_rr(§or[cont_offset], cont_size, dpnt); - }; - }; - - /* Fall back to the iso name if no RR name found */ - if (dpnt->name == NULL) { - char *cp; - - strcpy(name_buf, dpnt->isorec.name); - cp = strchr(name_buf, ';'); - if (cp != NULL) { - *cp = '\0'; - } - - dpnt->name = strdup(name_buf); - } - - return 0; -} /* parse_rr */ - - -static int -FDECL4(check_rr_dates, struct directory_entry *, dpnt, - struct directory_entry *, current, - struct stat *, statbuf, - struct stat *,lstatbuf) -{ - int cont_extent, cont_offset, cont_size; - int offset; - unsigned char * pnt; - int len; - int same_file; - int same_file_type; - mode_t mode; - char time_buf[7]; - - - cont_extent = cont_offset = cont_size = 0; - same_file = 1; - same_file_type = 1; - - pnt = dpnt->rr_attributes; - len = dpnt->rr_attr_size; - /* - * We basically need to parse the rr attributes again, and - * dig out the dates and file types. - */ - while(len >= 4){ - if(pnt[3] != 1) { - fprintf (stderr, _("**Bad RR version attribute")); - return -1; - }; - - /* - * If we have POSIX file modes, make sure that the file type - * is the same. If it isn't, then we must always - * write the new file. - */ - if(strncmp((char *) pnt, "PX", 2) == 0) { - mode = isonum_733(pnt + 4); - if( (lstatbuf->st_mode & S_IFMT) != (mode & S_IFMT) ) - { - same_file_type = 0; - same_file = 0; - } - } - - if(strncmp((char *) pnt, "TF", 2) == 0) { - offset = 5; - if( pnt[4] & TF_CREATE ) - { - iso9660_date((char *) time_buf, lstatbuf->st_ctime); - if(memcmp(time_buf, pnt+offset, 7) == 0) - same_file = 0; - offset += 7; - } - if( pnt[4] & TF_MODIFY ) - { - iso9660_date((char *) time_buf, lstatbuf->st_mtime); - if(memcmp(time_buf, pnt+offset, 7) == 0) - same_file = 0; - offset += 7; - } - } - - if(strncmp((char *) pnt, "CE", 2) == 0) { - cont_extent = isonum_733(pnt+4); - cont_offset = isonum_733(pnt+12); - cont_size = isonum_733(pnt+20); - }; - - len -= pnt[2]; - pnt += pnt[2]; - if(len <= 3 && cont_extent) { - unsigned char sector[SECTOR_SIZE]; - - readsecs(cont_extent, sector, 1); - parse_rr(§or[cont_offset], cont_size, dpnt); - }; - }; - - /* - * If we have the same fundamental file type, then it is clearly - * safe to reuse the TRANS.TBL entry. - */ - if( same_file_type ) - { - current->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - } - - return same_file; -} - -struct directory_entry ** -FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, - int *, nent) -{ - unsigned char * cpnt; - unsigned char * cpnt1; - char * dirbuff; - int i; - struct iso_directory_record * idr; - int len; - struct directory_entry **pnt; - int rlen; - struct directory_entry **rtn; - int seen_rockridge; - unsigned char * tt_buf; - int tt_extent; - int tt_size; - - static int warning_given = 0; - - /* - * First, allocate a buffer large enough to read in the entire - * directory. - */ - dirbuff = (char *) e_malloc(isonum_733((unsigned char *)mrootp->size)); - - readsecs(isonum_733((unsigned char *)mrootp->extent), dirbuff, - isonum_733((unsigned char *)mrootp->size)/SECTOR_SIZE); - - /* - * Next look over the directory, and count up how many entries we - * have. - */ - len = isonum_733((unsigned char *)mrootp->size); - i = 0; - *nent = 0; - while(i < len ) - { - idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) - { - i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); - continue; - } - (*nent)++; - i += idr->length[0]; - } - - /* - * Now allocate the buffer which will hold the array we are - * about to return. - */ - rtn = (struct directory_entry **) e_malloc(*nent * sizeof(*rtn)); - - /* - * Finally, scan the directory one last time, and pick out the - * relevant bits of information, and store it in the relevant - * bits of the structure. - */ - i = 0; - pnt = rtn; - tt_extent = 0; - seen_rockridge = 0; - tt_size = 0; - while(i < len ) - { - idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) - { - i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); - continue; - } - *pnt = (struct directory_entry *) e_malloc(sizeof(**rtn)); - (*pnt)->next = NULL; - (*pnt)->isorec = *idr; - (*pnt)->starting_block = isonum_733((unsigned char *)idr->extent); - (*pnt)->size = isonum_733((unsigned char *)idr->size); - (*pnt)->priority = 0; - (*pnt)->name = NULL; - (*pnt)->got_rr_name = 0; - (*pnt)->table = NULL; - (*pnt)->whole_name = NULL; - (*pnt)->filedir = NULL; - (*pnt)->parent_rec = NULL; - /* - * Set this information so that we correctly cache previous - * session bits of information. - */ - (*pnt)->inode = (*pnt)->starting_block; - (*pnt)->dev = PREV_SESS_DEV; - (*pnt)->rr_attributes = NULL; - (*pnt)->rr_attr_size = 0; - (*pnt)->total_rr_attr_size = 0; - (*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY; - - /* - * Check for and parse any RR attributes for the file. - * All we are really looking for here is the original name - * of the file. - */ - rlen = idr->length[0] & 0xff; - cpnt = (unsigned char *) idr; - - rlen -= sizeof(struct iso_directory_record); - cpnt += sizeof(struct iso_directory_record); - - rlen += sizeof(idr->name); - cpnt -= sizeof(idr->name); - - rlen -= idr->name_len[0]; - cpnt += idr->name_len[0]; - - if((idr->name_len[0] & 1) == 0){ - cpnt++; - rlen--; - }; - - if( rlen != 0 ) - { - (*pnt)->total_rr_attr_size = (*pnt)->rr_attr_size = rlen; - (*pnt)->rr_attributes = e_malloc(rlen); - memcpy((*pnt)->rr_attributes, cpnt, rlen); - seen_rockridge = 1; - } - - /* - * Now zero out the remainder of the name field. - */ - cpnt = (unsigned char *) &(*pnt)->isorec.name; - cpnt += idr->name_len[0]; - memset(cpnt, 0, sizeof((*pnt)->isorec.name) - idr->name_len[0]); - - parse_rr((*pnt)->rr_attributes, rlen, *pnt); - - if( ((*pnt)->isorec.name_len[0] == 1) - && ( ((*pnt)->isorec.name[0] == 0) - || ((*pnt)->isorec.name[0] == 1)) ) - { - if( (*pnt)->name != NULL ) - { - free((*pnt)->name); - } - if( (*pnt)->whole_name != NULL ) - { - free((*pnt)->whole_name); - } - if( (*pnt)->isorec.name[0] == 0 ) - { - (*pnt)->name = strdup("."); - } - else - { - (*pnt)->name = strdup(".."); - } - } - -#ifdef DEBUG - fprintf(stderr, "got DE name: %s\n", (*pnt)->name); -#endif - - if( strncmp(idr->name, "TRANS.TBL", 9) == 0) - { - if( (*pnt)->name != NULL ) - { - free((*pnt)->name); - } - if( (*pnt)->whole_name != NULL ) - { - free((*pnt)->whole_name); - } - (*pnt)->name = strdup(""); - tt_extent = isonum_733((unsigned char *)idr->extent); - tt_size = isonum_733((unsigned char *)idr->size); - } - - pnt++; - i += idr->length[0]; - } - - /* - * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it - * to get the filenames of the files. Also, save the table info, just - * in case we need to use it. - */ - if( tt_extent != 0 && tt_size != 0 ) - { - tt_buf = (unsigned char *) e_malloc(tt_size); - readsecs(tt_extent, tt_buf, tt_size/SECTOR_SIZE); - - /* - * Loop through the file, examine each entry, and attempt to - * attach it to the correct entry. - */ - cpnt = tt_buf; - cpnt1 = tt_buf; - while( cpnt - tt_buf < tt_size ) - { - while(*cpnt1 != '\n' && *cpnt1 != '\0') cpnt1++; - *cpnt1 = '\0'; - - for(pnt = rtn, i = 0; i <*nent; i++, pnt++) - { - rlen = isonum_711((*pnt)->isorec.name_len); - if( strncmp((char *) cpnt + 2, (*pnt)->isorec.name, - rlen) == 0 - && cpnt[2+rlen] == ' ') - { - (*pnt)->table = e_malloc(strlen((char*)cpnt) - 33); - sprintf((*pnt)->table, "%c\t%s\n", - *cpnt, cpnt+37); - if( !(*pnt)->got_rr_name ) - { - if ((*pnt)->name != NULL) { - free((*pnt)->name); - } - (*pnt)->name = strdup((char *) cpnt+37); - } - break; - } - } - cpnt = cpnt1 + 1; - cpnt1 = cpnt; - } - - free(tt_buf); - } - else if( !seen_rockridge && !warning_given ) - { - /* - * Warn the user that iso (8.3) names were used because neither - * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were found. - */ - fprintf (stderr, _("Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) " - "name translations were found on previous session. " - "ISO (8.3) file names have been used instead.\n")); - warning_given = 1; - } - - if( dirbuff != NULL ) - { - free(dirbuff); - } - - return rtn; -} /* read_merging_directory */ - -/* - * Free any associated data related to the structures. - */ -int -FDECL2(free_mdinfo, struct directory_entry ** , ptr, int, len ) -{ - int i; - struct directory_entry **p; - - p = ptr; - for(i=0; iname != NULL ) - { - free((*p)->name); - } - - if( (*p)->whole_name != NULL ) - { - free((*p)->whole_name); - } - - if( (*p)->rr_attributes != NULL ) - { - free((*p)->rr_attributes); - } - - if( (*p)->table != NULL ) - { - free((*p)->table); - } - - free(*p); - - } - - free(ptr); - return 0; -} - -/* - * Search the list to see if we have any entries from the previous - * session that match this entry. If so, copy the extent number - * over so we don't bother to write it out to the new session. - */ - -int -FDECL6(check_prev_session, struct directory_entry ** , ptr, int, len, - struct directory_entry *, curr_entry, - struct stat *, statbuf, struct stat *, lstatbuf, - struct directory_entry **, odpnt) -{ - int i; - - for( i=0; i < len; i++ ) - { - if( ptr[i] == NULL ) - { - continue; - } - -#if 0 - if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 - && ptr[i]->name[0] == '\0' ) - { - continue; - } - if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 - && ptr[i]->name[0] == 1) - { - continue; - } -#else - if( ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0 ) - { - continue; - } - if( ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0 ) - { - continue; - } -#endif - - if( ptr[i]->name != NULL - && strcmp(ptr[i]->name, curr_entry->name) != 0 ) - { - continue; - } - - /* - * We know that the files have the same name. If they also have - * the same file type (i.e. file, dir, block, etc), then we - * can safely reuse the TRANS.TBL entry for this file. - * The check_rr_dates function will do this for us. - * - * Verify that the file type and dates are consistent. - * If not, we probably have a different file, and we need - * to write it out again. - */ - if( (ptr[i]->rr_attributes != NULL) - && (check_rr_dates(ptr[i], curr_entry, statbuf, lstatbuf)) ) - { - goto found_it; - } - - - /* - * Verify size and timestamp. If rock ridge is in use, we need - * to compare dates from RR too. Directories are special, we - * calculate their size later. - */ - if( (curr_entry->isorec.flags[0] & 2) == 0 - && ptr[i]->size != curr_entry->size ) - { - goto found_it; - } - - if( memcmp(ptr[i]->isorec.date, curr_entry->isorec.date,7) != 0 ) - { - goto found_it; - } - - /* - * Never ever reuse directory extents. See comments in - * tree.c for an explaination of why this must be the case. - */ - if( (curr_entry->isorec.flags[0] & 2) != 0 ) - { - goto found_it; - } - - memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8); - curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - goto found_it; - } - return 0; - -found_it: - if( odpnt != NULL ) - { - *odpnt = ptr[i]; - } - else - { - free(ptr[i]); - } - ptr[i] = NULL; - return 0; -} - -/* - * merge_isofs: Scan an existing image, and return a pointer - * to the root directory for this image. - */ -struct iso_directory_record * FDECL1(merge_isofs, char *, path) -{ - char buffer[SECTOR_SIZE]; - int file_addr; - int i; - struct iso_primary_descriptor * pri = NULL; - struct iso_directory_record * rootp; - struct iso_volume_descriptor * vdp; - - /* - * Start by opening up the image and searching for the volume header. - * Ultimately, we need to search for volume headers in multiple places - * because we might be starting with a multisession image. - * FIXME(eric). - */ - -#ifndef USE_SCG - in_image = fopen(path, "rb"); - if( in_image == NULL ) - { - return NULL; - } -#else - if (strchr(path, '/')) { - in_image = fopen(path, "rb"); - if( in_image == NULL ) { - return NULL; - } - } else { - if (scsidev_open(path) < 0) - return NULL; - } -#endif - - get_session_start(&file_addr); - - for(i = 0; i< 100; i++) - { - if (readsecs(file_addr/SECTOR_SIZE, &buffer, - sizeof(buffer)/SECTOR_SIZE) != sizeof(buffer)) - error (10, errno, _("Read error on old image %s\n"), path); - - vdp = (struct iso_volume_descriptor *)buffer; - - if( (strncmp(vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) - && (isonum_711((unsigned char *) vdp->type) == ISO_VD_PRIMARY) ) - { - break; - } - file_addr += SECTOR_SIZE; - } - - if( i == 100 ) - { - return NULL; - } - - pri = (struct iso_primary_descriptor *)vdp; - - /* - * Check the blocksize of the image to make sure it is compatible. - */ - if( (isonum_723 ((unsigned char *) pri->logical_block_size) != SECTOR_SIZE) - || (isonum_723 ((unsigned char *) pri->volume_set_size) != 1) ) - { - return NULL; - } - - /* - * Get the location and size of the root directory. - */ - rootp = (struct iso_directory_record *) - malloc(sizeof(struct iso_directory_record)); - - memcpy(rootp, pri->root_directory_record, sizeof(*rootp)); - - return rootp; -} - -void FDECL3(merge_remaining_entries, struct directory *, this_dir, - struct directory_entry **, pnt, - int, n_orig) -{ - int i; - struct directory_entry * s_entry; - unsigned int ttbl_extent = 0; - unsigned int ttbl_index = 0; - char whole_path[1024]; - - /* - * Whatever is leftover in the list needs to get merged back - * into the directory. - */ - for( i=0; i < n_orig; i++ ) - { - if( pnt[i] == NULL ) - { - continue; - } - - if( pnt[i]->name != NULL && pnt[i]->whole_name == NULL) - { - /* - * Set the name for this directory. - */ - strcpy(whole_path, this_dir->de_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, pnt[i]->name); - - pnt[i]->whole_name = strdup(whole_path); - } - - if( pnt[i]->name != NULL - && strcmp(pnt[i]->name, "") == 0 ) - { - ttbl_extent = isonum_733((unsigned char *) pnt[i]->isorec.extent); - ttbl_index = i; - continue; - } - /* - * Skip directories for now - these need to be treated - * differently. - */ - if( (pnt[i]->isorec.flags[0] & 2) != 0 ) - { - /* - * FIXME - we need to insert this directory into the - * tree, so that the path tables we generate will - * be correct. - */ - if( (strcmp(pnt[i]->name, ".") == 0) - || (strcmp(pnt[i]->name, "..") == 0) ) - { - free(pnt[i]); - pnt[i] = NULL; - continue; - } - else - { - merge_old_directory_into_tree(pnt[i], this_dir); - } - } - pnt[i]->next = this_dir->contents; - pnt[i]->filedir = this_dir; - this_dir->contents = pnt[i]; - pnt[i] = NULL; - } - - - /* - * If we don't have an entry for the translation table, then - * don't bother trying to copy the starting extent over. - * Note that it is possible that if we are copying the entire - * directory, the entry for the translation table will have already - * been inserted into the linked list and removed from the old - * entries list, in which case we want to leave the extent number - * as it was before. - */ - if( ttbl_extent == 0 ) - { - return; - } - - /* - * Finally, check the directory we are creating to see whether - * there are any new entries in it. If there are not, we can - * reuse the same translation table. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* - * Don't care about '.' or '..'. They are never in the table - * anyways. - */ - if( s_entry->name != NULL && strcmp(s_entry->name, ".") == 0 ) - { - continue; - } - if( s_entry->name != NULL && strcmp(s_entry->name, "..") == 0 ) - { - continue; - } - if( strcmp(s_entry->name, "") == 0) - { - continue; - } - if( (s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0 ) - { - return; - } - } - - /* - * Locate the translation table, and re-use the same extent. - * It isn't clear that there should ever be one in there already - * so for now we try and muddle through the best we can. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, "") == 0) - { - fprintf (stderr, "Should never get here\n"); - set_733(s_entry->isorec.extent, ttbl_extent); - return; - } - } - - pnt[ttbl_index]->next = this_dir->contents; - pnt[ttbl_index]->filedir = this_dir; - this_dir->contents = pnt[ttbl_index]; - pnt[ttbl_index] = NULL; -} - - -/* - * Here we have a case of a directory that has completely disappeared from - * the face of the earth on the tree we are mastering from. Go through and - * merge it into the tree, as well as everything beneath it. - * - * Note that if a directory has been moved for some reason, this will - * incorrectly pick it up and attempt to merge it back into the old - * location. FIXME(eric). - */ -static int -FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, - struct directory *, parent) -{ - struct directory_entry **contents = NULL; - int i; - int n_orig; - struct directory * this_dir, *next_brother; - char whole_path[1024]; - - this_dir = (struct directory *) e_malloc(sizeof(struct directory)); - memset(this_dir, 0, sizeof(struct directory)); - this_dir->next = NULL; - this_dir->subdir = NULL; - this_dir->self = dpnt; - this_dir->contents = NULL; - this_dir->size = 0; - this_dir->extent = 0; - this_dir->depth = parent->depth + 1; - this_dir->parent = parent; - if(!parent->subdir) - parent->subdir = this_dir; - else { - next_brother = parent->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = this_dir; - } - - /* - * Set the name for this directory. - */ - strcpy(whole_path, parent->de_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, dpnt->name); - this_dir->de_name = strdup(whole_path); - this_dir->whole_name = strdup(whole_path); - - /* - * Now fill this directory using information from the previous - * session. - */ - contents = read_merging_directory(&dpnt->isorec, &n_orig); - /* - * Start by simply copying the '.', '..' and non-directory - * entries to this directory. Technically we could let - * merge_remaining_entries handle this, but it gets rather confused - * by the '.' and '..' entries. - */ - for(i=0; i < n_orig; i ++ ) - { - /* - * We can always reuse the TRANS.TBL in this particular case. - */ - contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - - if( ((contents[i]->isorec.flags[0] & 2) != 0) - && (i >= 2) ) - { - continue; - } - - /* - * If we have a directory, don't reuse the extent number. - */ - if( (contents[i]->isorec.flags[0] & 2) != 0 ) - { - memset(contents[i]->isorec.extent, 0, 8); - - if( strcmp(contents[i]->name, ".") == 0 ) - this_dir->dir_flags |= DIR_HAS_DOT; - - if( strcmp(contents[i]->name, "..") == 0 ) - this_dir->dir_flags |= DIR_HAS_DOTDOT; - } - - /* - * Set the whole name for this file. - */ - strcpy(whole_path, this_dir->whole_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, contents[i]->name); - - contents[i]->whole_name = strdup(whole_path); - - contents[i]->next = this_dir->contents; - contents[i]->filedir = this_dir; - this_dir->contents = contents[i]; - contents[i] = NULL; - } - - /* - * Zero the extent number for ourselves. - */ - memset(dpnt->isorec.extent, 0, 8); - - /* - * Anything that is left are other subdirectories that need to be merged. - */ - merge_remaining_entries(this_dir, contents, n_orig); - free_mdinfo(contents, n_orig); -#if 0 - /* - * This is no longer required. The post-scan sort will handle - * all of this for us. - */ - sort_n_finish(this_dir); -#endif - - return 0; -} - - -char * cdwrite_data = NULL; - -int -FDECL1(get_session_start, int *, file_addr) -{ - char * pnt; - -#ifdef CDWRITE_DETERMINES_FIRST_WRITABLE_ADDRESS - /* - * FIXME(eric). We need to coordinate with cdwrite to obtain - * the parameters. For now, we assume we are writing the 2nd session, - * so we start from the session that starts at 0. - */ - - *file_addr = (16 << 11); - - /* - * We need to coordinate with cdwrite to get the next writable address - * from the device. Here is where we use it. - */ - session_start = last_extent = last_extent_written = cdwrite_result(); - -#else - - if( cdwrite_data == NULL ) - error (1, 0, _("Special parameters for cdwrite not specified with -C\n")); - - /* - * Next try and find the ',' in there which delimits the two numbers. - */ - pnt = strchr(cdwrite_data, ','); - if( pnt == NULL ) - error (1, 0, _("Malformed cdwrite parameters\n")); - - *pnt = '\0'; - if (file_addr != NULL) { - *file_addr = atol(cdwrite_data) * SECTOR_SIZE; - } - pnt++; - - session_start = last_extent = last_extent_written = atol(pnt); - - pnt--; - *pnt = ','; - -#endif - return 0; -} - -/* - * This function scans the directory tree, looking for files, and it makes - * note of everything that is found. We also begin to construct the ISO9660 - * directory entries, so that we can determine how large each directory is. - */ - -int -FDECL2(merge_previous_session,struct directory *, this_dir, - struct iso_directory_record *, mrootp) -{ - struct directory_entry **orig_contents = NULL; - struct directory_entry * odpnt = NULL; - int n_orig; - struct directory_entry * s_entry; - int status, lstatus; - struct stat statbuf, lstatbuf; - - /* - * Parse the same directory in the image that we are merging - * for multisession stuff. - */ - orig_contents = read_merging_directory(mrootp, &n_orig); - if( orig_contents == NULL ) - { - return 0; - } - - -/* Now we scan the directory itself, and look at what is inside of it. */ - - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - status = stat_filter(s_entry->whole_name, &statbuf); - lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); - - /* - * We always should create an entirely new directory tree whenever - * we generate a new session, unless there were *no* changes whatsoever - * to any of the directories, in which case it would be kind of pointless - * to generate a new session. - * - * I believe it is possible to rigorously prove that any change anywhere - * in the filesystem will force the entire tree to be regenerated - * because the modified directory will get a new extent number. Since - * each subdirectory of the changed directory has a '..' entry, all of - * them will need to be rewritten too, and since the parent directory - * of the modified directory will have an extent pointer to the directory - * it too will need to be rewritten. Thus we will never be able to reuse - * any directory information when writing new sessions. - * - * We still check the previous session so we can mark off the equivalent - * entry in the list we got from the original disc, however. - */ - - /* - * The check_prev_session function looks for an identical entry in - * the previous session. If we see it, then we copy the extent - * number to s_entry, and cross it off the list. - */ - check_prev_session(orig_contents, n_orig, s_entry, - &statbuf, &lstatbuf, &odpnt); - - if(S_ISDIR(statbuf.st_mode) && odpnt != NULL) - { - int dflag; - - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - struct directory * child; - - child = find_or_create_directory(this_dir, - s_entry->whole_name, - s_entry, 1); - dflag = merge_previous_session(child, - &odpnt->isorec); - /* If unable to scan directory, mark this as a non-directory */ - if(!dflag) - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - free(odpnt); - odpnt = NULL; - } - } - } - - /* - * Whatever is left over, are things which are no longer in the tree - * on disk. We need to also merge these into the tree. - */ - merge_remaining_entries(this_dir, orig_contents, n_orig); - free_mdinfo(orig_contents, n_orig); - - return 1; -} - diff --git a/util/mkisofs/name.c b/util/mkisofs/name.c deleted file mode 100644 index 272471e93..000000000 --- a/util/mkisofs/name.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * File name.c - map full Unix file names to unique 8.3 names that - * would be valid on DOS. - * - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - 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, 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 "config.h" -#include "mkisofs.h" - -#include - -extern int allow_leading_dots; - -/* - * Function: iso9660_file_length - * - * Purpose: Map file name to 8.3 format, return length - * of result. - * - * Arguments: name file name we need to map. - * sresult directory entry structure to contain mapped name. - * dirflag flag indicating whether this is a directory or not. - * - * Notes: This procedure probably needs to be rationalized somehow. - * New options to affect the behavior of this function - * would also be nice to have. - */ -int FDECL3(iso9660_file_length, - const char*, name, - struct directory_entry *, sresult, - int, dirflag) -{ - char * c; - int chars_after_dot = 0; - int chars_before_dot = 0; - int current_length = 0; - int extra = 0; - int ignore = 0; - char * last_dot; - const char * pnt; - int priority = 32767; - char * result; - int seen_dot = 0; - int seen_semic = 0; - int tildes = 0; - - result = sresult->isorec.name; - - /* - * For the '.' entry, generate the correct record, and return - * 1 for the length. - */ - if(strcmp(name,".") == 0) - { - if(result) - { - *result = 0; - } - return 1; - } - - /* - * For the '..' entry, generate the correct record, and return - * 1 for the length. - */ - if(strcmp(name,"..") == 0) - { - if(result) - { - *result++ = 1; - *result++ = 0; - } - return 1; - } - - /* - * Now scan the directory one character at a time, and figure out - * what to do. - */ - pnt = name; - - /* - * Find the '.' that we intend to use for the extension. Usually this - * is the last dot, but if we have . followed by nothing or a ~, we - * would consider this to be unsatisfactory, and we keep searching. - */ - last_dot = strrchr (pnt,'.'); - if( (last_dot != NULL) - && ( (last_dot[1] == '~') - || (last_dot[1] == '\0')) ) - { - c = last_dot; - *c = '\0'; - last_dot = strrchr (pnt,'.'); - *c = '.'; - } - - while(*pnt) - { -#ifdef VMS - if( strcmp(pnt,".DIR;1") == 0 ) - { - break; - } -#endif - - /* - * This character indicates a Unix style of backup file - * generated by some editors. Lower the priority of - * the file. - */ - if(*pnt == '#') - { - priority = 1; - pnt++; - continue; - } - - /* - * This character indicates a Unix style of backup file - * generated by some editors. Lower the priority of - * the file. - */ - if(*pnt == '~') - { - priority = 1; - tildes++; - pnt++; - continue; - } - - /* - * This might come up if we had some joker already try and put - * iso9660 version numbers into the file names. This would be - * a silly thing to do on a Unix box, but we check for it - * anyways. If we see this, then we don't have to add our - * own version number at the end. - * UNLESS the ';' is part of the filename and no version - * number is following. [VK] - */ - if(*pnt == ';') - { - /* [VK] */ - if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9')) - { - pnt++; - ignore++; - continue; - } - } - - /* - * If we have a name with multiple '.' characters, we ignore everything - * after we have gotten the extension. - */ - if(ignore) - { - pnt++; - continue; - } - - /* - * Spin past any iso9660 version number we might have. - */ - if(seen_semic) - { - if(*pnt >= '0' && *pnt <= '9') - { - *result++ = *pnt; - } - extra++; - pnt++; - continue; - } - - /* - * If we have full names, the names we generate will not - * work on a DOS machine, since they are not guaranteed - * to be 8.3. Nonetheless, in many cases this is a useful - * option. We still only allow one '.' character in the - * name, however. - */ - if(full_iso9660_filenames) - { - /* Here we allow a more relaxed syntax. */ - if(*pnt == '.') - { - if (seen_dot) - { - ignore++; - continue; - } - seen_dot++; - } - if(current_length < 30) - { - if( !isascii (*pnt)) - { - *result++ = '_'; - } - else - { - *result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt); - } - } - } - else - { - /* - * Dos style filenames. We really restrict the - * names here. - */ - /* It would be nice to have .tar.gz transform to .tgz, - * .ps.gz to .psz, ... - */ - if(*pnt == '.') - { - if (!chars_before_dot && !allow_leading_dots) - { - /* DOS can't read files with dot first */ - chars_before_dot++; - if (result) - { - *result++ = '_'; /* Substitute underscore */ - } - } - else if( pnt != last_dot ) - { - /* - * If this isn't the dot that we use for the extension, - * then change the character into a '_' instead. - */ - if(chars_before_dot < 8) - { - chars_before_dot++; - if(result) - { - *result++ = '_'; - } - } - } - else - { - if (seen_dot) - { - ignore++; continue; - } - if(result) - { - *result++ = '.'; - } - seen_dot++; - } - } - else - { - if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot) - || (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) ) - { - if(result) - { - switch (*pnt) - { - default: - if( !isascii (*pnt) ) - { - *result++ = '_'; - } - else - { - *result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt; - } - break; - - /* - * Descriptions of DOS's 'Parse Filename' - * (function 29H) describes V1 and V2.0+ - * separator and terminator characters. - * These characters in a DOS name make - * the file visible but un-manipulable - * (all useful operations error off. - */ - /* separators */ - case '+': - case '=': - case '%': /* not legal DOS filename */ - case ':': - case ';': /* already handled */ - case '.': /* already handled */ - case ',': /* already handled */ - case '\t': - case ' ': - /* V1 only separators */ - case '/': - case '"': - case '[': - case ']': - /* terminators */ - case '>': - case '<': - case '|': - /* Hmm - what to do here? Skip? - * Win95 looks like it substitutes '_' - */ - *result++ = '_'; - break; - } /* switch (*pnt) */ - } /* if (result) */ - } /* if (chars_{after,before}_dot) ... */ - } /* else *pnt == '.' */ - } /* else DOS file names */ - current_length++; - pnt++; - } /* while (*pnt) */ - - /* - * OK, that wraps up the scan of the name. Now tidy up a few other - * things. - */ - - /* - * Look for emacs style of numbered backups, like foo.c.~3~. If - * we see this, convert the version number into the priority - * number. In case of name conflicts, this is what would end - * up being used as the 'extension'. - */ - if(tildes == 2) - { - int prio1 = 0; - pnt = name; - while (*pnt && *pnt != '~') - { - pnt++; - } - if (*pnt) - { - pnt++; - } - while(*pnt && *pnt != '~') - { - prio1 = 10*prio1 + *pnt - '0'; - pnt++; - } - priority = prio1; - } - - /* - * If this is not a directory, force a '.' in case we haven't - * seen one, and add a version number if we haven't seen one - * of those either. - */ - if (!dirflag) - { - if (!seen_dot && !omit_period) - { - if (result) *result++ = '.'; - extra++; - } - if(!omit_version_number && !seen_semic) - { - if(result) - { - *result++ = ';'; - *result++ = '1'; - }; - extra += 2; - } - } - - if(result) - { - *result++ = 0; - } - sresult->priority = priority; - - return (chars_before_dot + chars_after_dot + seen_dot + extra); -} diff --git a/util/mkisofs/rock.c b/util/mkisofs/rock.c deleted file mode 100644 index a7a39f774..000000000 --- a/util/mkisofs/rock.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * File rock.c - generate RRIP records for iso9660 filesystems. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 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, 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 "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#endif -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif - -#include "mkisofs.h" -#include "iso9660.h" -#include -#include - -#ifdef DOESNT_WORK - -#ifdef NON_UNIXFS -#define S_ISLNK(m) (0) -#else -#ifndef S_ISLNK -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#endif - -#else -#include -#endif - -#define SU_VERSION 1 - -#define SL_ROOT 8 -#define SL_PARENT 4 -#define SL_CURRENT 2 -#define SL_CONTINUE 1 - -#define CE_SIZE 28 -#define CL_SIZE 12 -#define ER_SIZE 8 -#define NM_SIZE 5 -#define PL_SIZE 12 -#define PN_SIZE 20 -#define PX_SIZE 36 -#define RE_SIZE 4 -#define SL_SIZE 20 -#define ZZ_SIZE 15 -#ifdef __QNX__ -#define TF_SIZE (5 + 4 * 7) -#else -#define TF_SIZE (5 + 3 * 7) -#endif - -/* If we need to store this number of bytes, make sure we - do not box ourselves in so that we do not have room for - a CE entry for the continuation record */ - -#define MAYBE_ADD_CE_ENTRY(BYTES) \ - ((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0) - -/* - * Buffer to build RR attributes - */ - -static unsigned char Rock[16384]; -static unsigned char symlink_buff[256]; -static int ipnt = 0; -static int recstart = 0; -static int currlen = 0; -static int mainrec = 0; -static int reclimit; - -static void add_CE_entry __PR((void)); - -static void add_CE_entry(){ - if(recstart) - set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart); - Rock[ipnt++] ='C'; - Rock[ipnt++] ='E'; - Rock[ipnt++] = CE_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - recstart = ipnt; - currlen = 0; - if(!mainrec) mainrec = ipnt; - reclimit = SECTOR_SIZE - 8; /* Limit to one sector */ -} - -#ifdef __STDC__ -int generate_rock_ridge_attributes (char * whole_name, char * name, - struct directory_entry * s_entry, - struct stat * statbuf, - struct stat * lstatbuf, - int deep_opt) -#else -int generate_rock_ridge_attributes (whole_name, name, - s_entry, - statbuf, - lstatbuf, - deep_opt) -char * whole_name; char * name; struct directory_entry * s_entry; -struct stat * statbuf, *lstatbuf; -int deep_opt; -#endif -{ - int flagpos, flagval; - int need_ce; - - statbuf = statbuf; /* this shuts up unreferenced compiler warnings */ - mainrec = recstart = ipnt = 0; - reclimit = 0xf8; - - /* no need to fill in the RR stuff if we won't see the file */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - return 0; - - /* Obtain the amount of space that is currently used for the directory - record. Assume max for name, since name conflicts may cause us - to rename the file later on */ - currlen = sizeof(s_entry->isorec); - - /* Identify that we are using the SUSP protocol */ - if(deep_opt & NEED_SP){ - Rock[ipnt++] ='S'; - Rock[ipnt++] ='P'; - Rock[ipnt++] = 7; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 0xbe; - Rock[ipnt++] = 0xef; - Rock[ipnt++] = 0; - }; - - /* First build the posix name field */ - Rock[ipnt++] ='R'; - Rock[ipnt++] ='R'; - Rock[ipnt++] = 5; - Rock[ipnt++] = SU_VERSION; - flagpos = ipnt; - flagval = 0; - Rock[ipnt++] = 0; /* We go back and fix this later */ - - if(strcmp(name,".") && strcmp(name,"..")){ - char * npnt; - int remain, use; - - remain = strlen(name); - npnt = name; - - while(remain){ - use = remain; - need_ce = 0; - /* Can we fit this SUSP and a CE entry? */ - if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { - use = reclimit - currlen - CE_SIZE - (ipnt - recstart); - need_ce++; - } - - /* Only room for 256 per SUSP field */ - if(use > 0xf8) use = 0xf8; - - /* First build the posix name field */ - Rock[ipnt++] ='N'; - Rock[ipnt++] ='M'; - Rock[ipnt++] = NM_SIZE + use; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = (remain != use ? 1 : 0); - flagval |= (1<<3); - strncpy((char *)&Rock[ipnt], npnt, use); - npnt += use; - ipnt += use; - remain -= use; - if(remain && need_ce) add_CE_entry(); - }; - }; - - /* - * Add the posix modes - */ - if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='X'; - Rock[ipnt++] = PX_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<0); - set_733((char*)Rock + ipnt, lstatbuf->st_mode); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_nlink); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_uid); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_gid); - ipnt += 8; - - /* - * Check for special devices - */ -#ifndef NON_UNIXFS - if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) { - if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='N'; - Rock[ipnt++] = PN_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<1); -#if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV) - set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev )); - ipnt += 8; - set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev)); - ipnt += 8; -#else - /* - * If we don't have sysmacros.h, then we have to guess as to how - * best to pick apart the device number for major/minor. - * Note: this may very well be wrong for many systems, so - * it is always best to use the major/minor macros if the - * system supports it. - */ - if(sizeof(dev_t) <= 2) { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8)); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff); - ipnt += 8; - } - else if(sizeof(dev_t) <= 4) { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff); - ipnt += 8; - } - else { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev); - ipnt += 8; - } -#endif - }; -#endif - /* - * Check for and symbolic links. VMS does not have these. - */ - if (S_ISLNK(lstatbuf->st_mode)){ - int lenpos, lenval, j0, j1; - int nchar; - unsigned char * cpnt, *cpnt1; - nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff)); - symlink_buff[nchar < 0 ? 0 : nchar] = 0; - nchar = strlen((char *) symlink_buff); - set_733(s_entry->isorec.size, 0); - cpnt = &symlink_buff[0]; - flagval |= (1<<2); - - if (! split_SL_field) - { - int sl_bytes = 0; - for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) - { - if (*cpnt1 == '/') - { - sl_bytes += 4; - } - else - { - sl_bytes += 1; - } - } - if (sl_bytes > 250) - { - /* - * the symbolic link won't fit into one SL System Use Field - * print an error message and continue with splited one - */ - fprintf (stderr, _("symbolic link `%s' too long for one SL System Use Field, splitting"), cpnt); - } - if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry(); - } - - while(nchar){ - if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='S'; - Rock[ipnt++] ='L'; - lenpos = ipnt; - Rock[ipnt++] = SL_SIZE; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 0; /* Flags */ - lenval = 5; - while(*cpnt){ - cpnt1 = (unsigned char *) strchr((char *) cpnt, '/'); - if(cpnt1) { - nchar--; - *cpnt1 = 0; - }; - - /* We treat certain components in a special way. */ - if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_PARENT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - nchar -= 2; - } else if(cpnt[0] == '.' && cpnt[1] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_CURRENT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - nchar -= 1; - } else if(cpnt[0] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_ROOT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - } else { - /* If we do not have enough room for a component, start - a new continuations segment now */ - if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) : - MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt))) - { - add_CE_entry(); - if(cpnt1) - { - *cpnt1 = '/'; - nchar++; - cpnt1 = NULL; /* A kluge so that we can restart properly */ - } - break; - } - j0 = strlen((char *) cpnt); - while(j0) { - j1 = j0; - if(j1 > 0xf8) j1 = 0xf8; - need_ce = 0; - if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { - j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart); - need_ce++; - } - Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0); - Rock[ipnt++] = j1; - strncpy((char *) Rock + ipnt, (char *) cpnt, j1); - ipnt += j1; - lenval += j1 + 2; - cpnt += j1; - nchar -= j1; /* Number we processed this time */ - j0 -= j1; - if(need_ce) { - add_CE_entry(); - if(cpnt1) { - *cpnt1 = '/'; - nchar++; - cpnt1 = NULL; /* A kluge so that we can restart properly */ - } - break; - } - } - }; - if(cpnt1) { - cpnt = cpnt1 + 1; - } else - break; - } - Rock[lenpos] = lenval; - if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */ - } /* while nchar */ - } /* Is a symbolic link */ - /* - * Add in the Rock Ridge TF time field - */ - if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry(); - Rock[ipnt++] ='T'; - Rock[ipnt++] ='F'; - Rock[ipnt++] = TF_SIZE; - Rock[ipnt++] = SU_VERSION; -#ifdef __QNX__ - Rock[ipnt++] = 0x0f; -#else - Rock[ipnt++] = 0x0e; -#endif - flagval |= (1<<7); -#ifdef __QNX__ - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime); - ipnt += 7; -#endif - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime); - ipnt += 7; - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime); - ipnt += 7; - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime); - ipnt += 7; - - /* - * Add in the Rock Ridge RE time field - */ - if(deep_opt & NEED_RE){ - if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry(); - Rock[ipnt++] ='R'; - Rock[ipnt++] ='E'; - Rock[ipnt++] = RE_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<6); - }; - /* - * Add in the Rock Ridge PL record, if required. - */ - if(deep_opt & NEED_PL){ - if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='L'; - Rock[ipnt++] = PL_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - flagval |= (1<<5); - }; - - /* - * Add in the Rock Ridge CL field, if required. - */ - if(deep_opt & NEED_CL){ - if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='C'; - Rock[ipnt++] ='L'; - Rock[ipnt++] = CL_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - flagval |= (1<<4); - }; - -#ifndef VMS - /* If transparent compression was requested, fill in the correct - field for this file */ - if(transparent_compression && - S_ISREG(lstatbuf->st_mode) && - strlen(name) > 3 && - strcmp(name + strlen(name) - 3,".gZ") == 0){ - FILE * zipfile; - char * checkname; - unsigned int file_size; - unsigned char header[8]; - int OK_flag; - - /* First open file and verify that the correct algorithm was used */ - file_size = 0; - OK_flag = 1; - - zipfile = fopen(whole_name, "rb"); - if (fread (header, 1, sizeof (header), zipfile) != sizeof(header)) - error (1, errno, "fread"); - - /* Check some magic numbers from gzip. */ - if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0; - /* Make sure file was blocksized. */ - if(((header[3] & 0x40) == 0)) OK_flag = 0; - /* OK, now go to the end of the file and get some more info */ - if(OK_flag){ - int status; - status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END); - if(status == -1) OK_flag = 0; - } - if(OK_flag){ - if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header)) - OK_flag = 0; - else { - int blocksize; - blocksize = (header[3] << 8) | header[2]; - file_size = ((unsigned int)header[7] << 24) | - ((unsigned int)header[6] << 16) | - ((unsigned int)header[5] << 8) | header[4]; -#if 0 - fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size); -#endif - if(blocksize != SECTOR_SIZE) OK_flag = 0; - } - } - fclose(zipfile); - - checkname = strdup(whole_name); - checkname[strlen(whole_name)-3] = 0; - zipfile = fopen(checkname, "rb"); - if(zipfile) { - OK_flag = 0; - fprintf (stderr, _("Unable to insert transparent compressed file - name conflict\n")); - fclose(zipfile); - } - - free(checkname); - - if(OK_flag){ - if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry(); - Rock[ipnt++] ='Z'; - Rock[ipnt++] ='Z'; - Rock[ipnt++] = ZZ_SIZE; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 'g'; /* Identify compression technique used */ - Rock[ipnt++] = 'z'; - Rock[ipnt++] = 3; - set_733((char*)Rock + ipnt, file_size); /* Real file size */ - ipnt += 8; - }; - } -#endif - /* - * Add in the Rock Ridge CE field, if required. We use this for the - * extension record that is stored in the root directory. - */ - if(deep_opt & NEED_CE) add_CE_entry(); - /* - * Done filling in all of the fields. Now copy it back to a buffer for the - * file in question. - */ - - /* Now copy this back to the buffer for the file */ - Rock[flagpos] = flagval; - - /* If there was a CE, fill in the size field */ - if(recstart) - set_733((char*)Rock + recstart - 8, ipnt - recstart); - - s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt); - s_entry->total_rr_attr_size = ipnt; - s_entry->rr_attr_size = (mainrec ? mainrec : ipnt); - memcpy(s_entry->rr_attributes, Rock, ipnt); - return ipnt; -} - -/* Guaranteed to return a single sector with the relevant info */ - -char * FDECL4(generate_rr_extension_record, char *, id, char *, descriptor, - char *, source, int *, size){ - int lipnt = 0; - char * pnt; - int len_id, len_des, len_src; - - len_id = strlen(id); - len_des = strlen(descriptor); - len_src = strlen(source); - Rock[lipnt++] ='E'; - Rock[lipnt++] ='R'; - Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src; - Rock[lipnt++] = 1; - Rock[lipnt++] = len_id; - Rock[lipnt++] = len_des; - Rock[lipnt++] = len_src; - Rock[lipnt++] = 1; - - memcpy(Rock + lipnt, id, len_id); - lipnt += len_id; - - memcpy(Rock + lipnt, descriptor, len_des); - lipnt += len_des; - - memcpy(Rock + lipnt, source, len_src); - lipnt += len_src; - - if(lipnt > SECTOR_SIZE) - error (1, 0, _("Extension record too long\n")); - pnt = (char *) e_malloc(SECTOR_SIZE); - memset(pnt, 0, SECTOR_SIZE); - memcpy(pnt, Rock, lipnt); - *size = lipnt; - return pnt; -} diff --git a/util/mkisofs/tree.c b/util/mkisofs/tree.c deleted file mode 100644 index 0d9cf6143..000000000 --- a/util/mkisofs/tree.c +++ /dev/null @@ -1,1865 +0,0 @@ -/* - * File tree.c - scan directory tree and build memory structures for iso9660 - * filesystem - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 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, 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 . - */ - -/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */ - -#include -#include -#include -#include - -#include "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif -#else -#include -#include -#include "vms.h" -extern char * strdup(const char *); -#endif - -/* - * Autoconf should be able to figure this one out for us and let us know - * whether the system has memmove or not. - */ -# ifndef HAVE_MEMMOVE -# define memmove(d, s, n) bcopy ((s), (d), (n)) -# endif - -#include "mkisofs.h" -#include "iso9660.h" -#include "match.h" - -#include - -#include "exclude.h" - -#ifdef DOESNT_WORK - -#ifdef NON_UNIXFS -#define S_ISLNK(m) (0) -#define S_ISSOCK(m) (0) -#define S_ISFIFO(m) (0) -#else -#ifndef S_ISLNK -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#ifndef S_ISSOCK -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) (0) -# endif -#endif -#endif - -#else -#include -#endif - - -#ifdef __SVR4 -extern char * strdup(const char *); -#endif - -static unsigned char symlink_buff[256]; - -static void stat_fix __PR((struct stat * st)); -static void generate_reloc_directory __PR((void)); - -static void DECL(attach_dot_entries, (struct directory * dirnode, - struct stat * parent_stat)); -static void DECL(delete_directory, (struct directory * parent, struct directory * child)); - -extern int verbose; - -struct stat fstatbuf; /* We use this for the artificial entries we create */ - -struct stat root_statbuf; /* Stat buffer for root directory */ - -struct directory * reloc_dir = NULL; - -static void -FDECL1(stat_fix, struct stat *, st) -{ - /* Remove the uid and gid, they will only be useful on the author's - system. */ - st->st_uid = 0; - st->st_gid = 0; - - /* - * Make sure the file modes make sense. Turn on all read bits. Turn - * on all exec/search bits if any exec/search bit is set. Turn off - * all write bits, and all special mode bits (on a r/o fs lock bits - * are useless, and with uid+gid 0 don't want set-id bits, either). - */ - st->st_mode |= 0444; -#ifndef _WIN32 /* make all file "executable" */ - if (st->st_mode & 0111) -#endif /* _WIN32 */ - st->st_mode |= 0111; - st->st_mode &= ~07222; -} - -int -FDECL2(stat_filter, char *, path, struct stat *, st) -{ - int result = stat(path, st); - if (result >= 0 && rationalize) - stat_fix(st); - - if ((unsigned) st->st_size > UINT32_MAX) - result = -1; - - return result; -} - -int -FDECL2(lstat_filter, char *, path, struct stat *, st) -{ - int result = lstat(path, st); - if (result >= 0 && rationalize) - stat_fix(st); - - if ((unsigned) st->st_size > UINT32_MAX) - result = -1; - - return result; -} - -static int FDECL1(sort_n_finish, struct directory *, this_dir) -{ - struct directory_entry * s_entry; - struct directory_entry * s_entry1; - struct directory_entry * table; - int count; - int d1; - int d2; - int d3; - int new_reclen; - char * c; - int status = 0; - int tablesize = 0; - char newname[34]; - char rootname[34]; - - /* Here we can take the opportunity to toss duplicate entries from the - directory. */ - - /* ignore if it's hidden */ - if(this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) - { - return 0; - } - - table = NULL; - - init_fstatbuf(); - - /* - * If we had artificially created this directory, then we might be - * missing the required '.' entries. Create these now if we need - * them. - */ - if( (this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) != - (DIR_HAS_DOT | DIR_HAS_DOTDOT) ) - { - attach_dot_entries(this_dir, &fstatbuf); - } - - flush_file_hash(); - s_entry = this_dir->contents; - while(s_entry) - { - /* ignore if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - s_entry = s_entry->next; - continue; - } - - /* - * First assume no conflict, and handle this case - */ - if(!(s_entry1 = find_file_hash(s_entry->isorec.name))) - { - add_file_hash(s_entry); - s_entry = s_entry->next; - continue; - } - - if(s_entry1 == s_entry) - error (1, 0, _("Fatal goof\n")); - - /* - * OK, handle the conflicts. Try substitute names until we come - * up with a winner - */ - strcpy(rootname, s_entry->isorec.name); - if(full_iso9660_filenames) - { - if(strlen(rootname) > 27) rootname[27] = 0; - } - - /* - * Strip off the non-significant part of the name so that we are left - * with a sensible root filename. If we don't find a '.', then try - * a ';'. - */ - c = strchr(rootname, '.'); - if (c) - *c = 0; - else - { - c = strchr(rootname, ';'); - if (c) *c = 0; - } - for(d1 = 0; d1 < 36; d1++) - { - for(d2 = 0; d2 < 36; d2++) - { - for(d3 = 0; d3 < 36; d3++) - { - sprintf(newname,"%s.%c%c%c%s", rootname, - (d1 <= 9 ? '0' + d1 : 'A' + d1 - 10), - (d2 <= 9 ? '0' + d2 : 'A' + d2 - 10), - (d3 <= 9 ? '0' + d3 : 'A' + d3 - 10), - (s_entry->isorec.flags[0] == 2 || - omit_version_number ? "" : ";1")); - -#ifdef VMS - /* Sigh. VAXCRTL seems to be broken here */ - { - int ijk = 0; - while(newname[ijk]) - { - if(newname[ijk] == ' ') newname[ijk] = '0'; - ijk++; - } - } -#endif - - if(!find_file_hash(newname)) goto got_valid_name; - } - } - } - - /* - * If we fell off the bottom here, we were in real trouble. - */ - error (1, 0, _("Unable to generate unique name for file %s\n"), s_entry->name); - -got_valid_name: - /* - * OK, now we have a good replacement name. Now decide which one - * of these two beasts should get the name changed - */ - if(s_entry->priority < s_entry1->priority) - { - if( verbose > 0 ) - { - fprintf (stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, - s_entry->name, s_entry1->name); - } - s_entry->isorec.name_len[0] = strlen(newname); - new_reclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) + - strlen(newname); - if(use_RockRidge) - { - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - new_reclen += s_entry->rr_attr_size; - } - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - s_entry->isorec.length[0] = new_reclen; - strcpy(s_entry->isorec.name, newname); - } - else - { - delete_file_hash(s_entry1); - if( verbose > 0 ) - { - fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, - s_entry1->name, s_entry->name); - } - s_entry1->isorec.name_len[0] = strlen(newname); - new_reclen = sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name) + - strlen(newname); - if(use_RockRidge) - { - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - new_reclen += s_entry1->rr_attr_size; - } - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - s_entry1->isorec.length[0] = new_reclen; - strcpy(s_entry1->isorec.name, newname); - add_file_hash(s_entry1); - } - add_file_hash(s_entry); - s_entry = s_entry->next; - } - - if(generate_tables - && !find_file_hash("TRANS.TBL") - && (reloc_dir != this_dir) - && (this_dir->extent == 0) ) - { - /* - * First we need to figure out how big this table is - */ - for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if(strcmp(s_entry->name, ".") == 0 || - strcmp(s_entry->name, "..") == 0) continue; - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; - if(s_entry->table) tablesize += 35 + strlen(s_entry->table); - } - } - - if( tablesize > 0 ) - { - table = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(table, 0, sizeof(struct directory_entry)); - table->table = NULL; - table->next = this_dir->contents; - this_dir->contents = table; - - table->filedir = root; - table->isorec.flags[0] = 0; - table->priority = 32768; - iso9660_date(table->isorec.date, fstatbuf.st_mtime); - table->inode = TABLE_INODE; - table->dev = (dev_t) UNCACHED_DEVICE; - set_723(table->isorec.volume_sequence_number, volume_sequence_number); - set_733((char *) table->isorec.size, tablesize); - table->size = tablesize; - table->filedir = this_dir; -#ifdef ERIC_neverdef - table->de_flags |= INHIBIT_JOLIET_ENTRY; -#endif - table->name = strdup(""); - table->table = (char *) e_malloc(ROUND_UP(tablesize)); - memset(table->table, 0, ROUND_UP(tablesize)); - iso9660_file_length ("TRANS.TBL", table, 0); - - if(use_RockRidge) - { - fstatbuf.st_mode = 0444 | S_IFREG; - fstatbuf.st_nlink = 1; - generate_rock_ridge_attributes("", - "TRANS.TBL", table, - &fstatbuf, &fstatbuf, 0); - } - } - - /* - * We have now chosen the 8.3 names and we should now know the length - * of every entry in the directory. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* skip if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - continue; - } - - new_reclen = strlen(s_entry->isorec.name); - - /* - * First update the path table sizes for directories. - */ - if(s_entry->isorec.flags[0] == 2) - { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - path_table_size += new_reclen + sizeof(struct iso_path_table) - 1; - if (new_reclen & 1) path_table_size++; - } - else - { - new_reclen = 1; - if (this_dir == root && strlen(s_entry->name) == 1) - { - path_table_size += sizeof(struct iso_path_table); - } - } - } - if(path_table_size & 1) path_table_size++; /* For odd lengths we pad */ - s_entry->isorec.name_len[0] = new_reclen; - - new_reclen += - sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name); - - if (new_reclen & 1) - new_reclen++; - - new_reclen += s_entry->rr_attr_size; - - if (new_reclen & 1) new_reclen++; - - if(new_reclen > 0xff) - error (1, 0, _("Fatal error - RR overflow for file %s\n"), - s_entry->name); - s_entry->isorec.length[0] = new_reclen; - } - - status = sort_directory(&this_dir->contents); - if( status > 0 ) - { - fprintf (stderr, _("Unable to sort directory %s\n"), - this_dir->whole_name); - } - - /* - * If we are filling out a TRANS.TBL, generate the entries that will - * go in the thing. - */ - if(table) - { - count = 0; - for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){ - if(s_entry == table) continue; - if(!s_entry->table) continue; - if(strcmp(s_entry->name, ".") == 0 || - strcmp(s_entry->name, "..") == 0) continue; - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; - /* - * Warning: we cannot use the return value of sprintf because - * old BSD based sprintf() implementations will return - * a pointer to the result instead of a count. - */ - sprintf(table->table + count, "%c %-34s%s", - s_entry->table[0], - s_entry->isorec.name, s_entry->table+1); - count += strlen(table->table + count); - free(s_entry->table); - s_entry->table = NULL; - } - - if(count != tablesize) - error (1, 0, _("Translation table size mismatch %d %d\n"), - count, tablesize); - } - - /* - * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary - */ - s_entry = this_dir->contents; - this_dir->ce_bytes = 0; - while(s_entry) - { - /* skip if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - s_entry = s_entry->next; - continue; - } - - new_reclen = s_entry->isorec.length[0]; - if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) - this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - this_dir->size += new_reclen; - - /* See if continuation entries were used on disc */ - if(use_RockRidge && - s_entry->rr_attr_size != s_entry->total_rr_attr_size) - { - unsigned char * pnt; - int len; - int nbytes; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - - /* - * We make sure that each continuation entry record is not - * split across sectors, but each file could in theory have more - * than one CE, so we scan through and figure out what we need. - */ - while(len > 3) - { - if(pnt[0] == 'C' && pnt[1] == 'E') - { - nbytes = get_733((char *) pnt+20); - - if((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) this_dir->ce_bytes = - ROUND_UP(this_dir->ce_bytes); - /* Now store the block in the ce buffer */ - this_dir->ce_bytes += nbytes; - if(this_dir->ce_bytes & 1) this_dir->ce_bytes++; - } - len -= pnt[2]; - pnt += pnt[2]; - } - } - s_entry = s_entry->next; - } - return status; -} - -static void generate_reloc_directory() -{ - time_t current_time; - struct directory_entry *s_entry; - - /* Create an entry for our internal tree */ - time (¤t_time); - reloc_dir = (struct directory *) - e_malloc(sizeof(struct directory)); - memset(reloc_dir, 0, sizeof(struct directory)); - reloc_dir->parent = root; - reloc_dir->next = root->subdir; - root->subdir = reloc_dir; - reloc_dir->depth = 1; - reloc_dir->whole_name = strdup("./rr_moved"); - reloc_dir->de_name = strdup("rr_moved"); - reloc_dir->extent = 0; - - - /* Now create an actual directory entry */ - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(s_entry, 0, sizeof(struct directory_entry)); - s_entry->next = root->contents; - reloc_dir->self = s_entry; - - /* - * The rr_moved entry will not appear in the Joliet tree. - */ - reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - - root->contents = s_entry; - root->contents->name = strdup(reloc_dir->de_name); - root->contents->filedir = root; - root->contents->isorec.flags[0] = 2; - root->contents->priority = 32768; - iso9660_date(root->contents->isorec.date, current_time); - root->contents->inode = UNCACHED_INODE; - root->contents->dev = (dev_t) UNCACHED_DEVICE; - set_723(root->contents->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length (reloc_dir->de_name, root->contents, 1); - - if(use_RockRidge){ - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - generate_rock_ridge_attributes("", - "rr_moved", s_entry, - &fstatbuf, &fstatbuf, 0); - }; - - /* Now create the . and .. entries in rr_moved */ - /* Now create an actual directory entry */ - attach_dot_entries(reloc_dir, &root_statbuf); -} - -/* - * Function: attach_dot_entries - * - * Purpose: Create . and .. entries for a new directory. - * - * Notes: Only used for artificial directories that - * we are creating. - */ -static void FDECL2(attach_dot_entries, struct directory *, dirnode, - struct stat *, parent_stat) -{ - struct directory_entry *s_entry; - struct directory_entry *orig_contents; - int deep_flag = 0; - - init_fstatbuf(); - - orig_contents = dirnode->contents; - - if( (dirnode->dir_flags & DIR_HAS_DOTDOT) == 0 ) - { - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, - sizeof(struct directory_entry)); - s_entry->name = strdup(".."); - s_entry->whole_name = NULL; - s_entry->isorec.name_len[0] = 1; - s_entry->isorec.flags[0] = 2; /* Mark as a directory */ - iso9660_file_length ("..", s_entry, 1); - iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); - s_entry->filedir = dirnode->parent; - - dirnode->contents = s_entry; - dirnode->contents->next = orig_contents; - orig_contents = s_entry; - - if(use_RockRidge) - { - if( parent_stat == NULL ) - { - parent_stat = &fstatbuf; - } - generate_rock_ridge_attributes("", - "..", s_entry, - parent_stat, - parent_stat, 0); - } - dirnode->dir_flags |= DIR_HAS_DOTDOT; - } - - if( (dirnode->dir_flags & DIR_HAS_DOT) == 0 ) - { - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, - sizeof(struct directory_entry)); - s_entry->name = strdup("."); - s_entry->whole_name = NULL; - s_entry->isorec.name_len[0] = 1; - s_entry->isorec.flags[0] = 2; /* Mark as a directory */ - iso9660_file_length (".", s_entry, 1); - iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); - s_entry->filedir = dirnode; - - dirnode->contents = s_entry; - dirnode->contents->next = orig_contents; - - if(use_RockRidge) - { - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - - if( dirnode == root ) - { - deep_flag |= NEED_CE | NEED_SP; /* For extension record */ - } - - generate_rock_ridge_attributes("", - ".", s_entry, - &fstatbuf, &fstatbuf, deep_flag); - } - - dirnode->dir_flags |= DIR_HAS_DOT; - } - -} - -static void FDECL2(update_nlink, struct directory_entry *, s_entry, int, value) -{ - unsigned char * pnt; - int len; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len) - { - if(pnt[0] == 'P' && pnt[1] == 'X') - { - set_733((char *) pnt+12, value); - break; - } - len -= pnt[2]; - pnt += pnt[2]; - } -} - -static void FDECL1(increment_nlink, struct directory_entry *, s_entry) -{ - unsigned char * pnt; - int len, nlink; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len) - { - if(pnt[0] == 'P' && pnt[1] == 'X') - { - nlink = get_733((char *) pnt+12); - set_733((char *) pnt+12, nlink+1); - break; - } - len -= pnt[2]; - pnt += pnt[2]; - } -} - -void finish_cl_pl_entries(){ - struct directory_entry *s_entry, *s_entry1; - struct directory * d_entry; - - /* if the reloc_dir is hidden (empty), then return */ - if (reloc_dir->dir_flags & INHIBIT_ISO9660_ENTRY) - return; - - s_entry = reloc_dir->contents; - s_entry = s_entry->next->next; /* Skip past . and .. */ - for(; s_entry; s_entry = s_entry->next){ - /* skip if it's hidden */ - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - continue; - } - d_entry = reloc_dir->subdir; - while(d_entry){ - if(d_entry->self == s_entry) break; - d_entry = d_entry->next; - }; - if(!d_entry) - error (1, 0, _("Unable to locate directory parent\n")); - - /* First fix the PL pointer in the directory in the rr_reloc dir */ - s_entry1 = d_entry->contents->next; - set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8, - s_entry->filedir->extent); - - /* Now fix the CL pointer */ - s_entry1 = s_entry->parent_rec; - - set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8, - d_entry->extent); - - s_entry->filedir = reloc_dir; /* Now we can fix this */ - } - /* Next we need to modify the NLINK terms in the assorted root directory records - to account for the presence of the RR_MOVED directory */ - - increment_nlink(root->self); - increment_nlink(root->self->next); - d_entry = root->subdir; - while(d_entry){ - increment_nlink(d_entry->contents->next); - d_entry = d_entry->next; - }; -} - -/* - * Function: scan_directory_tree - * - * Purpose: Walk through a directory on the local machine - * filter those things we don't want to include - * and build our representation of a dir. - * - * Notes: - */ -int -FDECL3(scan_directory_tree,struct directory *, this_dir, - char *, path, - struct directory_entry *, de) -{ - DIR * current_dir; - char whole_path[1024]; - struct dirent * d_entry; - struct directory * parent; - int dflag; - char * old_path; - - if (verbose > 1) - { - fprintf (stderr, _("Scanning %s\n"), path); - } - - current_dir = opendir(path); - d_entry = NULL; - - /* Apparently NFS sometimes allows you to open the directory, but - then refuses to allow you to read the contents. Allow for this */ - - old_path = path; - - if(current_dir) d_entry = readdir(current_dir); - - if(!current_dir || !d_entry) - { - fprintf (stderr, _("Unable to open directory %s\n"), path); - de->isorec.flags[0] &= ~2; /* Mark as not a directory */ - if(current_dir) closedir(current_dir); - return 0; - } - - parent = de->filedir; - /* Set up the struct for the current directory, and insert it into the - tree */ - -#ifdef VMS - vms_path_fixup(path); -#endif - - /* - * if entry for this sub-directory is hidden, then hide this directory - */ - if (de->de_flags & INHIBIT_ISO9660_ENTRY) - this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; - - if (de->de_flags & INHIBIT_JOLIET_ENTRY) - this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; - - /* - * Now we scan the directory itself, and look at what is inside of it. - */ - dflag = 0; - while(1==1){ - - /* The first time through, skip this, since we already asked for - the first entry when we opened the directory. */ - if(dflag) d_entry = readdir(current_dir); - dflag++; - - if(!d_entry) break; - - /* OK, got a valid entry */ - - /* If we do not want all files, then pitch the backups. */ - if(!all_files){ - if( strchr(d_entry->d_name,'~') - || strchr(d_entry->d_name,'#')) - { - if( verbose > 0 ) - { - fprintf (stderr, _("Ignoring file %s\n"), d_entry->d_name); - } - continue; - } - } - - if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path)) - error (1, 0, _("Overflow of stat buffer\n")); - - /* Generate the complete ASCII path for this file */ - strcpy(whole_path, path); -#ifndef VMS - if(whole_path[strlen(whole_path)-1] != '/') - strcat(whole_path, "/"); -#endif - strcat(whole_path, d_entry->d_name); - - /** Should we exclude this file ? */ - if (matches(d_entry->d_name) || matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Excluded by match: %s\n"), whole_path); - } - continue; - } - - if( generate_tables - && strcmp(d_entry->d_name, "TRANS.TBL") == 0 ) - { - /* - * Ignore this entry. We are going to be generating new - * versions of these files, and we need to ignore any - * originals that we might have found. - */ - if (verbose > 1) - { - fprintf (stderr, _("Excluded: %s\n"), whole_path); - } - continue; - } - - /* - * If we already have a '.' or a '..' entry, then don't - * insert new ones. - */ - if( strcmp(d_entry->d_name, ".") == 0 - && this_dir->dir_flags & DIR_HAS_DOT ) - { - continue; - } - - if( strcmp(d_entry->d_name, "..") == 0 - && this_dir->dir_flags & DIR_HAS_DOTDOT ) - { - continue; - } - -#if 0 - if (verbose > 1) fprintf(stderr, "%s\n",whole_path); -#endif - /* - * This actually adds the entry to the directory in question. - */ - insert_file_entry(this_dir, whole_path, d_entry->d_name); - } - closedir(current_dir); - - return 1; -} - - -/* - * Function: insert_file_entry - * - * Purpose: Insert one entry into our directory node. - * - * Note: - * This function inserts a single entry into the directory. It - * is assumed that all filtering and decision making regarding what - * we want to include has already been made, so the purpose of this - * is to insert one entry (file, link, dir, etc), into this directory. - * Note that if the entry is a dir (or if we are following links, - * and the thing it points to is a dir), then we will scan those - * trees before we return. - */ -int -FDECL3(insert_file_entry,struct directory *, this_dir, - char *, whole_path, - char *, short_name) -{ - struct stat statbuf, lstatbuf; - struct directory_entry * s_entry, *s_entry1; - int lstatus; - int status; - int deep_flag; - - status = stat_filter(whole_path, &statbuf); - - lstatus = lstat_filter(whole_path, &lstatbuf); - - if( (status == -1) && (lstatus == -1) ) - { - /* - * This means that the file doesn't exist, or isn't accessible. - * Sometimes this is because of NFS permissions problems. - */ - fprintf (stderr, _("Non-existant or inaccessible: %s\n"),whole_path); - return 0; - } - - if(this_dir == root && strcmp(short_name, ".") == 0) - root_statbuf = statbuf; /* Save this for later on */ - - /* We do this to make sure that the root entries are consistent */ - if(this_dir == root && strcmp(short_name, "..") == 0) - { - statbuf = root_statbuf; - lstatbuf = root_statbuf; - } - - if(S_ISLNK(lstatbuf.st_mode)) - { - - /* Here we decide how to handle the symbolic links. Here - we handle the general case - if we are not following - links or there is an error, then we must change - something. If RR is in use, it is easy, we let RR - describe the file. If not, then we punt the file. */ - - if((status || !follow_links)) - { - if(use_RockRidge) - { - status = 0; - statbuf.st_size = 0; - STAT_INODE(statbuf) = UNCACHED_INODE; - statbuf.st_dev = (dev_t) UNCACHED_DEVICE; - statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; - } else { - if(follow_links) - { - fprintf (stderr, - _("Unable to stat file %s - ignoring and continuing.\n"), - whole_path); - } - else - { - fprintf (stderr, - _("Symlink %s ignored - continuing.\n"), - whole_path); - return 0; /* Non Rock Ridge discs - ignore all symlinks */ - } - } - } - - /* Here we handle a different kind of case. Here we have - a symlink, but we want to follow symlinks. If we run - across a directory loop, then we need to pretend that - we are not following symlinks for this file. If this - is the first time we have seen this, then make this - seem as if there was no symlink there in the first - place */ - - if( follow_links - && S_ISDIR(statbuf.st_mode) ) - { - if( strcmp(short_name, ".") - && strcmp(short_name, "..") ) - { - if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) - { - if(!use_RockRidge) - { - fprintf (stderr, _("Already cached directory seen (%s)\n"), - whole_path); - return 0; - } - statbuf.st_size = 0; - STAT_INODE(statbuf) = UNCACHED_INODE; - statbuf.st_dev = (dev_t) UNCACHED_DEVICE; - statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; - } - else - { - lstatbuf = statbuf; - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - } - } - - /* - * For non-directories, we just copy the stat information over - * so we correctly include this file. - */ - if( follow_links - && !S_ISDIR(statbuf.st_mode) ) - { - lstatbuf = statbuf; - } - } - - /* - * Add directories to the cache so that we don't waste space even - * if we are supposed to be following symlinks. - */ - if( follow_links - && strcmp(short_name, ".") - && strcmp(short_name, "..") - && S_ISDIR(statbuf.st_mode) ) - { - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - - if(S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK))) - { - fprintf (stderr, _("File %s is not readable (%s) - ignoring\n"), - whole_path, strerror (errno)); - return 0; - } - - /* Add this so that we can detect directory loops with hard links. - If we are set up to follow symlinks, then we skip this checking. */ - if( !follow_links - && S_ISDIR(lstatbuf.st_mode) - && strcmp(short_name, ".") - && strcmp(short_name, "..") ) - { - if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) - error (1, 0, _("Directory loop - fatal goof (%s %lx %lu).\n"), - whole_path, (unsigned long) statbuf.st_dev, - (unsigned long) STAT_INODE(statbuf)); - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - - if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) && - !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) - && !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) && - !S_ISDIR(lstatbuf.st_mode)) { - fprintf (stderr, _("Unknown file type %s - ignoring and continuing.\n"), - whole_path); - return 0; - } - - /* Who knows what trash this is - ignore and continue */ - - if(status) - { - fprintf (stderr, - _("Unable to stat file %s - ignoring and continuing.\n"), - whole_path); - return 0; - } - - /* - * Check to see if we have already seen this directory node. - * If so, then we don't create a new entry for it, but we do want - * to recurse beneath it and add any new files we do find. - */ - if (S_ISDIR(statbuf.st_mode)) - { - int dflag; - - for( s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, short_name) == 0 ) - { - break; - } - } - if ( s_entry != NULL - && strcmp(short_name,".") - && strcmp(short_name,"..")) - { - struct directory * child; - - if ( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0) - { - for( s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, short_name) == 0 ) - { - break; - } - } - child = find_or_create_directory(reloc_dir, whole_path, - s_entry, 1); - } - else - { - child = find_or_create_directory(this_dir, whole_path, - s_entry, 1); - /* If unable to scan directory, mark this as a non-directory */ - } - dflag = scan_directory_tree(child, whole_path, s_entry); - if(!dflag) - { - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - } - return 0; - } - } - - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - s_entry->next = this_dir->contents; - memset(s_entry->isorec.extent, 0, 8); - this_dir->contents = s_entry; - deep_flag = 0; - s_entry->table = NULL; - - s_entry->name = strdup(short_name); - s_entry->whole_name = strdup (whole_path); - - s_entry->de_flags = 0; - - /* - * If the current directory is hidden, then hide all it's members - * otherwise check if this entry needs to be hidden as well */ - if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { - s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; - } - else if (strcmp(short_name,".") && strcmp(short_name,"..")) { - if (i_matches(short_name) || i_matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Hidden from ISO9660 tree: %s\n"), whole_path); - } - s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; - } - } - - if (this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - } - else if (strcmp(short_name,".") && strcmp(short_name,"..")) { - if (j_matches(short_name) || j_matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Hidden from Joliet tree: %s\n"), whole_path); - } - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - } - } - - s_entry->filedir = this_dir; - s_entry->isorec.flags[0] = 0; - s_entry->isorec.ext_attr_length[0] = 0; - iso9660_date(s_entry->isorec.date, statbuf.st_mtime); - s_entry->isorec.file_unit_size[0] = 0; - s_entry->isorec.interleave[0] = 0; - - if( strcmp(short_name, ".") == 0) - { - this_dir->dir_flags |= DIR_HAS_DOT; - } - - if( strcmp(short_name, "..") == 0) - { - this_dir->dir_flags |= DIR_HAS_DOTDOT; - } - - if( this_dir->parent - && this_dir->parent == reloc_dir - && strcmp(short_name, "..") == 0) - { - s_entry->inode = UNCACHED_INODE; - s_entry->dev = (dev_t) UNCACHED_DEVICE; - deep_flag = NEED_PL; - } - else - { - s_entry->inode = STAT_INODE(statbuf); - s_entry->dev = statbuf.st_dev; - } - set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length(short_name, s_entry, S_ISDIR(statbuf.st_mode)); - s_entry->rr_attr_size = 0; - s_entry->total_rr_attr_size = 0; - s_entry->rr_attributes = NULL; - - /* Directories are assigned sizes later on */ - if (!S_ISDIR(statbuf.st_mode)) - { - if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || - S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode) - || S_ISLNK(lstatbuf.st_mode)) - { - s_entry->size = 0; - statbuf.st_size = 0; - } - else - { - s_entry->size = statbuf.st_size; - } - - set_733((char *) s_entry->isorec.size, statbuf.st_size); - } - else - { - s_entry->isorec.flags[0] = 2; - } - - if (strcmp(short_name,".") && strcmp(short_name,"..") && - S_ISDIR(statbuf.st_mode) && this_dir->depth > RR_relocation_depth) - { - struct directory * child; - - if(!reloc_dir) generate_reloc_directory(); - - /* - * Replicate the entry for this directory. The old one will stay where it - * is, and it will be neutered so that it no longer looks like a directory. - * The new one will look like a directory, and it will be put in the reloc_dir. - */ - s_entry1 = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry1, s_entry, sizeof(struct directory_entry)); - s_entry1->table = NULL; - s_entry1->name = strdup(this_dir->contents->name); - s_entry1->whole_name = strdup(this_dir->contents->whole_name); - s_entry1->next = reloc_dir->contents; - reloc_dir->contents = s_entry1; - s_entry1->priority = 32768; - s_entry1->parent_rec = this_dir->contents; - - deep_flag = NEED_RE; - - if(use_RockRidge) - { - generate_rock_ridge_attributes(whole_path, - short_name, s_entry1, - &statbuf, &lstatbuf, deep_flag); - } - - deep_flag = 0; - - /* We need to set this temporarily so that the parent to this - is correctly determined. */ - s_entry1->filedir = reloc_dir; - child = find_or_create_directory(reloc_dir, whole_path, - s_entry1, 0); - scan_directory_tree(child, whole_path, s_entry1); - s_entry1->filedir = this_dir; - - statbuf.st_size = 0; - statbuf.st_mode &= 0777; - set_733((char *) s_entry->isorec.size, 0); - s_entry->size = 0; - s_entry->isorec.flags[0] = 0; - s_entry->inode = UNCACHED_INODE; - s_entry->de_flags |= RELOCATED_DIRECTORY; - deep_flag = NEED_CL; - } - - if(generate_tables - && strcmp(s_entry->name, ".") - && strcmp(s_entry->name, "..")) - { - char buffer[2048]; - int nchar; - switch(lstatbuf.st_mode & S_IFMT) - { - case S_IFDIR: - sprintf(buffer,"D\t%s\n", - s_entry->name); - break; -#ifdef S_IFBLK -/* extra for WIN32 - if it doesn't have the major/minor defined, then - S_IFBLK and S_IFCHR type files are unlikely to exist anyway ... - code similar to that in rock.c */ - -/* for some reason, MAJOR_IN_SYSMACROS isn't defined on a SunOS when - it should be, so see if major() is defined instead */ -/* -#if !(defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV)) -*/ -#ifndef major -#define major(dev) (sizeof(dev_t) <= 2 ? ((dev) >> 8) : \ - (sizeof(dev_t) <= 4 ? (((dev) >> 8) >> 8) : \ - (((dev) >> 16) >> 16))) -#define minor(dev) (sizeof(dev_t) <= 2 ? (dev) & 0xff : \ - (sizeof(dev_t) <= 4 ? (dev) & 0xffff : \ - (dev) & 0xffffffff)) -#endif - case S_IFBLK: - sprintf(buffer,"B\t%s\t%lu %lu\n", - s_entry->name, - (unsigned long) major(statbuf.st_rdev), - (unsigned long) minor(statbuf.st_rdev)); - break; -#endif -#ifdef S_IFIFO - case S_IFIFO: - sprintf(buffer,"P\t%s\n", - s_entry->name); - break; -#endif -#ifdef S_IFCHR - case S_IFCHR: - sprintf(buffer,"C\t%s\t%lu %lu\n", - s_entry->name, - (unsigned long) major(statbuf.st_rdev), - (unsigned long) minor(statbuf.st_rdev)); - break; -#endif -#ifdef S_IFLNK - case S_IFLNK: - nchar = readlink(whole_path, - (char *)symlink_buff, - sizeof(symlink_buff)); - symlink_buff[nchar < 0 ? 0 : nchar] = 0; - sprintf(buffer,"L\t%s\t%s\n", - s_entry->name, symlink_buff); - break; -#endif -#ifdef S_IFSOCK - case S_IFSOCK: - sprintf(buffer,"S\t%s\n", - s_entry->name); - break; -#endif - case S_IFREG: - default: - sprintf(buffer,"F\t%s\n", - s_entry->name); - break; - }; - s_entry->table = strdup(buffer); - } - - if(S_ISDIR(statbuf.st_mode)) - { - int dflag; - if (strcmp(short_name,".") && strcmp(short_name,"..")) - { - struct directory * child; - - child = find_or_create_directory(this_dir, whole_path, - s_entry, 1); - dflag = scan_directory_tree(child, whole_path, s_entry); - - if(!dflag) - { - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - if( child->contents == NULL ) - { - delete_directory(this_dir, child); - } - } - } - /* If unable to scan directory, mark this as a non-directory */ - } - - if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") == 0) - { - deep_flag |= NEED_CE | NEED_SP; /* For extension record */ - } - - /* Now figure out how much room this file will take in the - directory */ - - if(use_RockRidge) - { - generate_rock_ridge_attributes(whole_path, - short_name, s_entry, - &statbuf, &lstatbuf, deep_flag); - - } - - return 1; -} - - -void FDECL2(generate_iso9660_directories, struct directory *, node, FILE*, outfile){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt){ - if( dpnt->extent > session_start ) - { - generate_one_directory(dpnt, outfile); - } - if(dpnt->subdir) generate_iso9660_directories(dpnt->subdir, outfile); - dpnt = dpnt->next; - } -} - -/* - * Function: find_or_create_directory - * - * Purpose: Locate a directory entry in the tree, create if needed. - * - * Arguments: - */ -struct directory * FDECL4(find_or_create_directory, struct directory *, parent, - const char *, path, - struct directory_entry *, de, int, flag) -{ - struct directory * dpnt; - struct directory_entry * orig_de; - struct directory * next_brother; - const char * cpnt; - const char * pnt; - - orig_de = de; - - pnt = strrchr(path, PATH_SEPARATOR); - if( pnt == NULL ) - { - pnt = path; - } - else - { - pnt++; - } - - if( parent != NULL ) - { - dpnt = parent->subdir; - - while (dpnt) - { - /* - * Weird hack time - if there are two directories by the - * same name in the reloc_dir, they are not treated as the - * same thing unless the entire path matches completely. - */ - if( flag && strcmp(dpnt->de_name, pnt) == 0 ) - { - return dpnt; - } - dpnt = dpnt->next; - } - } - - /* - * We don't know if we have a valid directory entry for this one - * yet. If not, we need to create one. - */ - if( de == NULL ) - { - de = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(de, 0, sizeof(struct directory_entry)); - de->next = parent->contents; - parent->contents = de; - de->name = strdup(pnt); - de->filedir = parent; - de->isorec.flags[0] = 2; - de->priority = 32768; - de->inode = UNCACHED_INODE; - de->dev = (dev_t) UNCACHED_DEVICE; - set_723(de->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length (pnt, de, 1); - - init_fstatbuf(); - /* - * It doesn't exist for real, so we cannot add any Rock Ridge. - */ - if(use_RockRidge) - { - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - generate_rock_ridge_attributes("", - (char *) pnt, de, - &fstatbuf, - &fstatbuf, 0); - } - iso9660_date(de->isorec.date, fstatbuf.st_mtime); - - } - - /* - * If we don't have a directory for this one yet, then allocate it - * now, and patch it into the tree in the appropriate place. - */ - dpnt = (struct directory *) e_malloc(sizeof(struct directory)); - memset(dpnt, 0, sizeof(struct directory)); - dpnt->next = NULL; - dpnt->subdir = NULL; - dpnt->self = de; - dpnt->contents = NULL; - dpnt->whole_name = strdup(path); - cpnt = strrchr(path, PATH_SEPARATOR); - if(cpnt) - cpnt++; - else - cpnt = path; - dpnt->de_name = strdup(cpnt); - dpnt->size = 0; - dpnt->extent = 0; - dpnt->jextent = 0; - dpnt->jsize = 0; - - if( orig_de == NULL ) - { - struct stat xstatbuf; - int sts; - - /* - * Now add a . and .. entry in the directory itself. - * This is a little tricky - if the real directory - * exists, we need to stat it first. Otherwise, we - * use the fictitious fstatbuf which points to the time - * at which mkisofs was started. - */ - sts = stat_filter(parent->whole_name, &xstatbuf); - if( sts == 0 ) - { - attach_dot_entries(dpnt, &xstatbuf); - } - else - { - attach_dot_entries(dpnt, &fstatbuf); - } - } - - if(!parent || parent == root) - { - if (!root) - { - root = dpnt; /* First time through for root directory only */ - root->depth = 0; - root->parent = root; - } else { - dpnt->depth = 1; - if(!root->subdir) - { - root->subdir = dpnt; - } - else - { - next_brother = root->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = dpnt; - } - dpnt->parent = parent; - } - } - else - { - /* Come through here for normal traversal of tree */ -#ifdef DEBUG - fprintf(stderr,"%s(%d) ", path, dpnt->depth); -#endif - if(parent->depth > RR_relocation_depth) - error (1, 0, _("Directories too deep %s\n"), path); - - dpnt->parent = parent; - dpnt->depth = parent->depth + 1; - - if(!parent->subdir) - { - parent->subdir = dpnt; - } - else - { - next_brother = parent->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = dpnt; - } - } - - return dpnt; -} - -/* - * Function: delete_directory - * - * Purpose: Locate a directory entry in the tree, create if needed. - * - * Arguments: - */ -static void FDECL2(delete_directory, struct directory *, parent, struct directory *, child) -{ - struct directory * tdir; - - if( child->contents != NULL ) - error (1, 0, _("Unable to delete non-empty directory\n")); - - free(child->whole_name); - child->whole_name = NULL; - - free(child->de_name); - child->de_name = NULL; - - if( parent->subdir == child ) - { - parent->subdir = child->next; - } - else - { - for( tdir = parent->subdir; tdir->next != NULL; tdir = tdir->next ) - { - if( tdir->next == child ) - { - tdir->next = child->next; - break; - } - } - if( tdir == NULL ) - error (1, 0, _("Unable to locate child directory in parent list\n")); - } - free(child); - return; -} - -int FDECL1(sort_tree, struct directory *, node){ - struct directory * dpnt; - int ret = 0; - - dpnt = node; - - while (dpnt){ - ret = sort_n_finish(dpnt); - if( ret ) - { - break; - } - - if(dpnt->subdir) sort_tree(dpnt->subdir); - dpnt = dpnt->next; - } - return ret; -} - -void FDECL1(dump_tree, struct directory *, node){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt){ - fprintf(stderr,"%4d %5d %s\n",dpnt->extent, dpnt->size, dpnt->de_name); - if(dpnt->subdir) dump_tree(dpnt->subdir); - dpnt = dpnt->next; - } -} - -void FDECL1(update_nlink_field, struct directory *, node) -{ - struct directory * dpnt; - struct directory * xpnt; - struct directory_entry * s_entry; - int i; - - dpnt = node; - - while (dpnt) - { - if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { - dpnt = dpnt->next; - continue; - } - - /* - * First, count up the number of subdirectories this guy has. - */ - for(i=0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) - if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0) - i++; - /* - * Next check to see if we have any relocated directories - * in this directory. The nlink field will include these - * as real directories when they are properly relocated. - * - * In the non-rockridge disk, the relocated entries appear - * as zero length files. - */ - for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) - { - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 && - (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) - { - i++; - } - } - /* - * Now update the field in the Rock Ridge entry. - */ - update_nlink(dpnt->self, i + 2); - - /* - * Update the '.' entry for this directory. - */ - update_nlink(dpnt->contents, i + 2); - - /* - * Update all of the '..' entries that point to this guy. - */ - for(xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) - update_nlink(xpnt->contents->next, i + 2); - - if(dpnt->subdir) update_nlink_field(dpnt->subdir); - dpnt = dpnt->next; - } -} - -/* - * something quick and dirty to locate a file given a path - * recursively walks down path in filename until it finds the - * directory entry for the desired file - */ -struct directory_entry * FDECL2(search_tree_file, struct directory *, - node,char *, filename) -{ - struct directory_entry * depnt; - struct directory * dpnt; - char * p1; - char * rest; - char * subdir; - - /* - * strip off next directory name from filename - */ - subdir = strdup(filename); - - if( (p1=strchr(subdir, '/')) == subdir ) - { - fprintf (stderr, _("call to search_tree_file with an absolute path, stripping\n")); - fprintf (stderr, _("initial path separator. Hope this was intended...\n")); - memmove(subdir, subdir+1, strlen(subdir)-1); - p1 = strchr(subdir, '/'); - } - - /* - * do we need to find a subdirectory - */ - if (p1) - { - *p1 = '\0'; - -#ifdef DEBUG_TORITO - fprintf(stderr,"Looking for subdir called %s\n",p1); -#endif - - rest = p1+1; - -#ifdef DEBUG_TORITO - fprintf(stderr,"Remainder of path name is now %s\n", rest); -#endif - - dpnt = node->subdir; - while( dpnt ) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n", dpnt->extent, dpnt->size, - dpnt->de_name); -#endif - if (!strcmp(subdir, dpnt->de_name)) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"Calling next level with filename = %s", rest); -#endif - return(search_tree_file( dpnt, rest )); - } - dpnt = dpnt->next; - } - - /* if we got here means we couldnt find the subdir */ - return (NULL); - } - else - { - /* - * look for a normal file now - */ - depnt = node->contents; - while (depnt) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n",depnt->isorec.extent, - depnt->size, depnt->name); -#endif - if (!strcmp(filename, depnt->name)) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"Found our file %s", filename); -#endif - return(depnt); - } - depnt = depnt->next; - } - /* - * if we got here means we couldnt find the subdir - */ - return (NULL); - } - fprintf (stderr, "We cant get here in search_tree_file :-/ \n"); -} - -void init_fstatbuf() -{ - time_t current_time; - - if(fstatbuf.st_ctime == 0) - { - time (¤t_time); - if( rationalize ) - { - fstatbuf.st_uid = 0; - fstatbuf.st_gid = 0; - } - else - { - fstatbuf.st_uid = getuid(); - fstatbuf.st_gid = getgid(); - } - fstatbuf.st_ctime = current_time; - fstatbuf.st_mtime = current_time; - fstatbuf.st_atime = current_time; - } -} diff --git a/util/mkisofs/write.c b/util/mkisofs/write.c deleted file mode 100644 index e1cdd213e..000000000 --- a/util/mkisofs/write.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * Program write.c - dump memory structures to file for iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 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, 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 "config.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "mkisofs.h" -#include "iso9660.h" -#include "msdos_partition.h" - -#ifdef __SVR4 -extern char * strdup(const char *); -#endif - -#ifdef VMS -extern char * strdup(const char *); -#endif - - -/* Max number of sectors we will write at one time */ -#define NSECT 16 - -/* Counters for statistics */ - -static int table_size = 0; -static int total_dir_size = 0; -static int rockridge_size = 0; -static struct directory ** pathlist; -static int next_path_index = 1; -static int sort_goof; - -struct output_fragment * out_tail; -struct output_fragment * out_list; - -struct iso_primary_descriptor vol_desc; - -static int root_gen __PR((void)); -static int generate_path_tables __PR((void)); -static int file_gen __PR((void)); -static int dirtree_dump __PR((void)); - -/* Routines to actually write the disc. We write sequentially so that - we could write a tape, or write the disc directly */ - - -#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof(vol_desc.X)) - -void FDECL2(set_721, char *, pnt, unsigned int, i) -{ - pnt[0] = i & 0xff; - pnt[1] = (i >> 8) & 0xff; -} - -void FDECL2(set_722, char *, pnt, unsigned int, i) -{ - pnt[0] = (i >> 8) & 0xff; - pnt[1] = i & 0xff; -} - -void FDECL2(set_723, char *, pnt, unsigned int, i) -{ - pnt[3] = pnt[0] = i & 0xff; - pnt[2] = pnt[1] = (i >> 8) & 0xff; -} - -void FDECL2(set_731, char *, pnt, unsigned int, i) -{ - pnt[0] = i & 0xff; - pnt[1] = (i >> 8) & 0xff; - pnt[2] = (i >> 16) & 0xff; - pnt[3] = (i >> 24) & 0xff; -} - -void FDECL2(set_732, char *, pnt, unsigned int, i) -{ - pnt[3] = i & 0xff; - pnt[2] = (i >> 8) & 0xff; - pnt[1] = (i >> 16) & 0xff; - pnt[0] = (i >> 24) & 0xff; -} - -int FDECL1(get_731, char *, p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -int FDECL1(get_733, char *, p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -void FDECL2(set_733, char *, pnt, unsigned int, i) -{ - pnt[7] = pnt[0] = i & 0xff; - pnt[6] = pnt[1] = (i >> 8) & 0xff; - pnt[5] = pnt[2] = (i >> 16) & 0xff; - pnt[4] = pnt[3] = (i >> 24) & 0xff; -} - -void FDECL4(xfwrite, void *, buffer, uint64_t, count, uint64_t, size, FILE *, file) -{ - /* - * This is a hack that could be made better. XXXIs this the only place? - * It is definitely needed on Operating Systems that do not - * allow to write files that are > 2GB. - * If the system is fast enough to be able to feed 1400 KB/s - * writing speed of a DVD-R drive, use stdout. - * If the system cannot do this reliable, you need to use this - * hacky option. - */ - static int idx = 0; - if (split_output != 0 && - (idx == 0 || ftell(file) >= (1024 * 1024 * 1024) )) { - char nbuf[512]; - extern char *outfile; - - if (idx == 0) - unlink(outfile); - sprintf(nbuf, "%s_%02d", outfile, idx++); - file = freopen(nbuf, "wb", file); - if (file == NULL) - error (1, errno, _("Cannot open `%s'"), nbuf); - - } - while(count) - { - size_t got = fwrite (buffer, size, count, file); - - if (got != count) - error (1, errno, _("cannot fwrite %llu*%llu\n"), size, count); - count-=got,*(char**)&buffer+=size*got; - } -} - -struct deferred_write -{ - struct deferred_write * next; - char * table; - uint64_t extent; - uint64_t size; - char * name; -}; - -static struct deferred_write * dw_head = NULL, * dw_tail = NULL; - -uint64_t last_extent_written = 0; -static unsigned int path_table_index; -static time_t begun; - -/* We recursively walk through all of the directories and assign extent - numbers to them. We have already assigned extent numbers to everything that - goes in front of them */ - -static int FDECL1(assign_directory_addresses, struct directory *, node) -{ - int dir_size; - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - /* skip if it's hidden */ - if(dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { - dpnt = dpnt->next; - continue; - } - - /* - * If we already have an extent for this (i.e. it came from - * a multisession disc), then don't reassign a new extent. - */ - dpnt->path_index = next_path_index++; - if( dpnt->extent == 0 ) - { - dpnt->extent = last_extent; - dir_size = (dpnt->size + (SECTOR_SIZE - 1)) >> 11; - - last_extent += dir_size; - - /* - * Leave room for the CE entries for this directory. Keep them - * close to the reference directory so that access will be - * quick. - */ - if(dpnt->ce_bytes) - { - last_extent += ROUND_UP(dpnt->ce_bytes) >> 11; - } - } - - if(dpnt->subdir) - { - assign_directory_addresses(dpnt->subdir); - } - - dpnt = dpnt->next; - } - return 0; -} - -static void FDECL3(write_one_file, char *, filename, - uint64_t, size, FILE *, outfile) -{ - char buffer[SECTOR_SIZE * NSECT]; - FILE * infile; - int64_t remain; - size_t use; - - - if ((infile = fopen(filename, "rb")) == NULL) - error (1, errno, _("cannot open %s\n"), filename); - remain = size; - - while(remain > 0) - { - use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain); - use = ROUND_UP(use); /* Round up to nearest sector boundary */ - memset(buffer, 0, use); - if (fread(buffer, 1, use, infile) == 0) - error (1, errno, _("cannot read %llu bytes from %s"), use, filename); - xfwrite(buffer, 1, use, outfile); - last_extent_written += use/SECTOR_SIZE; -#if 0 - if((last_extent_written % 1000) < use/SECTOR_SIZE) - { - fprintf(stderr,"%d..", last_extent_written); - } -#else - if((last_extent_written % 5000) < use/SECTOR_SIZE) - { - time_t now; - time_t the_end; - double frac; - - time(&now); - frac = last_extent_written / (double)last_extent; - the_end = begun + (now - begun) / frac; - fprintf (stderr, _("%6.2f%% done, estimate finish %s"), - frac * 100., ctime(&the_end)); - } -#endif - remain -= use; - } - fclose(infile); -} /* write_one_file(... */ - -static void FDECL1(write_files, FILE *, outfile) -{ - struct deferred_write * dwpnt, *dwnext; - dwpnt = dw_head; - while(dwpnt) - { - if(dwpnt->table) - { - write_one_file (dwpnt->table, dwpnt->size, outfile); - table_size += dwpnt->size; - free (dwpnt->table); - } - else - { - -#ifdef VMS - vms_write_one_file(dwpnt->name, dwpnt->size, outfile); -#else - write_one_file(dwpnt->name, dwpnt->size, outfile); -#endif - free(dwpnt->name); - } - - dwnext = dwpnt; - dwpnt = dwpnt->next; - free(dwnext); - } -} /* write_files(... */ - -#if 0 -static void dump_filelist() -{ - struct deferred_write * dwpnt; - dwpnt = dw_head; - while(dwpnt) - { - fprintf(stderr, "File %s\n",dwpnt->name); - dwpnt = dwpnt->next; - } - fprintf(stderr,"\n"); -} -#endif - -static int FDECL2(compare_dirs, const void *, rr, const void *, ll) -{ - char * rpnt, *lpnt; - struct directory_entry ** r, **l; - - r = (struct directory_entry **) rr; - l = (struct directory_entry **) ll; - rpnt = (*r)->isorec.name; - lpnt = (*l)->isorec.name; - - /* - * If the entries are the same, this is an error. - */ - if( strcmp(rpnt, lpnt) == 0 ) - { - sort_goof++; - } - - /* - * Put the '.' and '..' entries on the head of the sorted list. - * For normal ASCII, this always happens to be the case, but out of - * band characters cause this not to be the case sometimes. - * - * FIXME(eric) - these tests seem redundant, in taht the name is - * never assigned these values. It will instead be \000 or \001, - * and thus should always be sorted correctly. I need to figure - * out why I thought I needed this in the first place. - */ -#if 0 - if( strcmp(rpnt, ".") == 0 ) return -1; - if( strcmp(lpnt, ".") == 0 ) return 1; - - if( strcmp(rpnt, "..") == 0 ) return -1; - if( strcmp(lpnt, "..") == 0 ) return 1; -#else - /* - * The code above is wrong (as explained in Eric's comment), leading to incorrect - * sort order iff the -L option ("allow leading dots") is in effect and a directory - * contains entries that start with a dot. - * - * (TF, Tue Dec 29 13:49:24 CET 1998) - */ - if((*r)->isorec.name_len[0] == 1 && *rpnt == 0) return -1; /* '.' */ - if((*l)->isorec.name_len[0] == 1 && *lpnt == 0) return 1; - - if((*r)->isorec.name_len[0] == 1 && *rpnt == 1) return -1; /* '..' */ - if((*l)->isorec.name_len[0] == 1 && *lpnt == 1) return 1; -#endif - - while(*rpnt && *lpnt) - { - if(*rpnt == ';' && *lpnt != ';') return -1; - if(*rpnt != ';' && *lpnt == ';') return 1; - - if(*rpnt == ';' && *lpnt == ';') return 0; - - if(*rpnt == '.' && *lpnt != '.') return -1; - if(*rpnt != '.' && *lpnt == '.') return 1; - - if((unsigned char)*rpnt < (unsigned char)*lpnt) return -1; - if((unsigned char)*rpnt > (unsigned char)*lpnt) return 1; - rpnt++; lpnt++; - } - if(*rpnt) return 1; - if(*lpnt) return -1; - return 0; -} - -/* - * Function: sort_directory - * - * Purpose: Sort the directory in the appropriate ISO9660 - * order. - * - * Notes: Returns 0 if OK, returns > 0 if an error occurred. - */ -int FDECL1(sort_directory, struct directory_entry **, sort_dir) -{ - int dcount = 0; - int xcount = 0; - int j; - int i, len; - struct directory_entry * s_entry; - struct directory_entry ** sortlist; - - /* need to keep a count of how many entries are hidden */ - s_entry = *sort_dir; - while(s_entry) - { - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - xcount++; - dcount++; - s_entry = s_entry->next; - } - - if( dcount == 0 ) - { - return 0; - } - - /* - * OK, now we know how many there are. Build a vector for sorting. - */ - sortlist = (struct directory_entry **) - e_malloc(sizeof(struct directory_entry *) * dcount); - - j = dcount - 1; - dcount = 0; - s_entry = *sort_dir; - while(s_entry) - { - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - /* put any hidden entries at the end of the vector */ - sortlist[j--] = s_entry; - } - else - { - sortlist[dcount] = s_entry; - dcount++; - } - len = s_entry->isorec.name_len[0]; - s_entry->isorec.name[len] = 0; - s_entry = s_entry->next; - } - - /* - * Each directory is required to contain at least . and .. - */ - if( dcount < 2 ) - { - sort_goof = 1; - - } - else - { - /* only sort the non-hidden entries */ - sort_goof = 0; -#ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), - (int (*)(const void *, const void *))compare_dirs); -#else - qsort(sortlist, dcount, sizeof(struct directory_entry *), - compare_dirs); -#endif - - /* - * Now reassemble the linked list in the proper sorted order - * We still need the hidden entries, as they may be used in the - * Joliet tree. - */ - for(i=0; inext = sortlist[i+1]; - } - - sortlist[dcount+xcount-1]->next = NULL; - *sort_dir = sortlist[0]; - } - - free(sortlist); - return sort_goof; -} - -static int root_gen() -{ - init_fstatbuf(); - - root_record.length[0] = 1 + sizeof(struct iso_directory_record) - - sizeof(root_record.name); - root_record.ext_attr_length[0] = 0; - set_733((char *) root_record.extent, root->extent); - set_733((char *) root_record.size, ROUND_UP(root->size)); - iso9660_date(root_record.date, root_statbuf.st_mtime); - root_record.flags[0] = 2; - root_record.file_unit_size[0] = 0; - root_record.interleave[0] = 0; - set_723(root_record.volume_sequence_number, volume_sequence_number); - root_record.name_len[0] = 1; - return 0; -} - -static void FDECL1(assign_file_addresses, struct directory *, dpnt) -{ - struct directory * finddir; - struct directory_entry * s_entry; - struct file_hash *s_hash; - struct deferred_write * dwpnt; - char whole_path[1024]; - - while (dpnt) - { - s_entry = dpnt->contents; - for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) - { - /* - * If we already have an extent for this entry, - * then don't assign a new one. It must have come - * from a previous session on the disc. Note that - * we don't end up scheduling the thing for writing - * either. - */ - if( isonum_733((unsigned char *) s_entry->isorec.extent) != 0 ) - { - continue; - } - - /* - * This saves some space if there are symlinks present - */ - s_hash = find_hash(s_entry->dev, s_entry->inode); - if(s_hash) - { - if(verbose > 2) - { - fprintf (stderr, _("Cache hit for %s%s%s\n"), s_entry->filedir->de_name, - SPATH_SEPARATOR, s_entry->name); - } - set_733((char *) s_entry->isorec.extent, s_hash->starting_block); - set_733((char *) s_entry->isorec.size, s_hash->size); - continue; - } - - /* - * If this is for a directory that is not a . or a .. entry, - * then look up the information for the entry. We have already - * assigned extents for directories, so we just need to - * fill in the blanks here. - */ - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") && - s_entry->isorec.flags[0] == 2) - { - finddir = dpnt->subdir; - while(1==1) - { - if(finddir->self == s_entry) break; - finddir = finddir->next; - if (!finddir) - error (1, 0, _("Fatal goof\n")); - } - set_733((char *) s_entry->isorec.extent, finddir->extent); - s_entry->starting_block = finddir->extent; - s_entry->size = ROUND_UP(finddir->size); - total_dir_size += s_entry->size; - add_hash(s_entry); - set_733((char *) s_entry->isorec.size, ROUND_UP(finddir->size)); - continue; - } - - - /* - * If this is . or .., then look up the relevant info from the - * tables. - */ - if(strcmp(s_entry->name,".") == 0) - { - set_733((char *) s_entry->isorec.extent, dpnt->extent); - - /* - * Set these so that the hash table has the - * correct information - */ - s_entry->starting_block = dpnt->extent; - s_entry->size = ROUND_UP(dpnt->size); - - add_hash(s_entry); - s_entry->starting_block = dpnt->extent; - set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->size)); - continue; - } - - if(strcmp(s_entry->name,"..") == 0) - { - if(dpnt == root) - { - total_dir_size += root->size; - } - set_733((char *) s_entry->isorec.extent, dpnt->parent->extent); - - /* - * Set these so that the hash table has the - * correct information - */ - s_entry->starting_block = dpnt->parent->extent; - s_entry->size = ROUND_UP(dpnt->parent->size); - - add_hash(s_entry); - s_entry->starting_block = dpnt->parent->extent; - set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->parent->size)); - continue; - } - - /* - * Some ordinary non-directory file. Just schedule the - * file to be written. This is all quite - * straightforward, just make a list and assign extents - * as we go. Once we get through writing all of the - * directories, we should be ready write out these - * files - */ - if(s_entry->size) - { - dwpnt = (struct deferred_write *) - e_malloc(sizeof(struct deferred_write)); - if(dw_tail) - { - dw_tail->next = dwpnt; - dw_tail = dwpnt; - } - else - { - dw_head = dwpnt; - dw_tail = dwpnt; - } - if(s_entry->inode == TABLE_INODE) - { - dwpnt->table = s_entry->table; - dwpnt->name = NULL; - sprintf(whole_path,"%s%sTRANS.TBL", - s_entry->filedir->whole_name, SPATH_SEPARATOR); - } - else - { - dwpnt->table = NULL; - strcpy(whole_path, s_entry->whole_name); - dwpnt->name = strdup(whole_path); - } - dwpnt->next = NULL; - dwpnt->size = s_entry->size; - dwpnt->extent = last_extent; - set_733((char *) s_entry->isorec.extent, last_extent); - s_entry->starting_block = last_extent; - add_hash(s_entry); - last_extent += ROUND_UP(s_entry->size) >> 11; - if(verbose > 2) - { - fprintf(stderr,"%llu %llu %s\n", s_entry->starting_block, - last_extent-1, whole_path); - } -#ifdef DBG_ISO - if((ROUND_UP(s_entry->size) >> 11) > 500) - { - fprintf (stderr, "Warning: large file %s\n", whole_path); - fprintf (stderr, "Starting block is %d\n", s_entry->starting_block); - fprintf (stderr, "Reported file size is %d extents\n", s_entry->size); - - } -#endif -#ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */ - - if(last_extent > (800000000 >> 11)) - { - /* - * More than 800Mb? Punt - */ - fprintf(stderr,"Extent overflow processing file %s\n", whole_path); - fprintf(stderr,"Starting block is %d\n", s_entry->starting_block); - fprintf(stderr,"Reported file size is %d extents\n", s_entry->size); - exit(1); - } -#endif - continue; - } - - /* - * This is for zero-length files. If we leave the extent 0, - * then we get screwed, because many readers simply drop files - * that have an extent of zero. Thus we leave the size 0, - * and just assign the extent number. - */ - set_733((char *) s_entry->isorec.extent, last_extent); - } - if(dpnt->subdir) - { - assign_file_addresses(dpnt->subdir); - } - dpnt = dpnt->next; - } -} /* assign_file_addresses(... */ - -static void FDECL1(free_one_directory, struct directory *, dpnt) -{ - struct directory_entry * s_entry; - struct directory_entry * s_entry_d; - - s_entry = dpnt->contents; - while(s_entry) - { - s_entry_d = s_entry; - s_entry = s_entry->next; - - if( s_entry_d->name != NULL ) - { - free (s_entry_d->name); - } - if( s_entry_d->whole_name != NULL ) - { - free (s_entry_d->whole_name); - } - free (s_entry_d); - } - dpnt->contents = NULL; -} /* free_one_directory(... */ - -static void FDECL1(free_directories, struct directory *, dpnt) -{ - while (dpnt) - { - free_one_directory(dpnt); - if(dpnt->subdir) free_directories(dpnt->subdir); - dpnt = dpnt->next; - } -} - -void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) -{ - unsigned int ce_address = 0; - char * ce_buffer; - unsigned int ce_index = 0; - unsigned int ce_size; - unsigned int dir_index; - char * directory_buffer; - int new_reclen; - struct directory_entry * s_entry; - struct directory_entry * s_entry_d; - unsigned int total_size; - - total_size = (dpnt->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - directory_buffer = (char *) e_malloc(total_size); - memset(directory_buffer, 0, total_size); - dir_index = 0; - - ce_size = (dpnt->ce_bytes + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - ce_buffer = NULL; - - if(ce_size) - { - ce_buffer = (char *) e_malloc(ce_size); - memset(ce_buffer, 0, ce_size); - - ce_index = 0; - - /* - * Absolute byte address of CE entries for this directory - */ - ce_address = last_extent_written + (total_size >> 11); - ce_address = ce_address << 11; - } - - s_entry = dpnt->contents; - while(s_entry) - { - /* skip if it's hidden */ - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - s_entry = s_entry->next; - continue; - } - - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector - */ - new_reclen = s_entry->isorec.length[0]; - if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) - { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - - memcpy(directory_buffer + dir_index, &s_entry->isorec, - sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) + s_entry->isorec.name_len[0]); - dir_index += sizeof(struct iso_directory_record) - - sizeof (s_entry->isorec.name)+ s_entry->isorec.name_len[0]; - - /* - * Add the Rock Ridge attributes, if present - */ - if(s_entry->rr_attr_size) - { - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - /* - * If the RR attributes were too long, then write the - * CE records, as required. - */ - if(s_entry->rr_attr_size != s_entry->total_rr_attr_size) - { - unsigned char * pnt; - int len, nbytes; - - /* - * Go through the entire record and fix up the CE entries - * so that the extent and offset are correct - */ - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len > 3) - { -#ifdef DEBUG - if (!ce_size) - { - fprintf(stderr,"Warning: ce_index(%d) && ce_address(%d) not initialized\n", - ce_index, ce_address); - } -#endif - - if(pnt[0] == 'C' && pnt[1] == 'E') - { - nbytes = get_733( (char *) pnt+20); - - if((ce_index & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) - { - ce_index = ROUND_UP(ce_index); - } - - set_733( (char *) pnt+4, - (ce_address + ce_index) >> 11); - set_733( (char *) pnt+12, - (ce_address + ce_index) & (SECTOR_SIZE - 1)); - - - /* - * Now store the block in the ce buffer - */ - memcpy(ce_buffer + ce_index, - pnt + pnt[2], nbytes); - ce_index += nbytes; - if(ce_index & 1) - { - ce_index++; - } - } - len -= pnt[2]; - pnt += pnt[2]; - } - - } - - rockridge_size += s_entry->total_rr_attr_size; - memcpy(directory_buffer + dir_index, s_entry->rr_attributes, - s_entry->rr_attr_size); - dir_index += s_entry->rr_attr_size; - } - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - s_entry_d = s_entry; - s_entry = s_entry->next; - - /* - * Joliet doesn't use the Rock Ridge attributes, so we free it here. - */ - if (s_entry_d->rr_attributes) - { - free(s_entry_d->rr_attributes); - s_entry_d->rr_attributes = NULL; - } - } - - if(dpnt->size != dir_index) - { - fprintf (stderr, _("Unexpected directory length %d %d %s\n"), dpnt->size, - dir_index, dpnt->de_name); - } - - xfwrite(directory_buffer, 1, total_size, outfile); - last_extent_written += total_size >> 11; - free(directory_buffer); - - if(ce_size) - { - if(ce_index != dpnt->ce_bytes) - { - fprintf (stderr, _("Continuation entry record length mismatch (%d %d).\n"), - ce_index, dpnt->ce_bytes); - } - xfwrite(ce_buffer, 1, ce_size, outfile); - last_extent_written += ce_size >> 11; - free(ce_buffer); - } - -} /* generate_one_directory(... */ - -static -void FDECL1(build_pathlist, struct directory *, node) -{ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - /* skip if it's hidden */ - if( (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0 ) - pathlist[dpnt->path_index] = dpnt; - - if(dpnt->subdir) build_pathlist(dpnt->subdir); - dpnt = dpnt->next; - } -} /* build_pathlist(... */ - -static int FDECL2(compare_paths, void const *, r, void const *, l) -{ - struct directory const *ll = *(struct directory * const *)l; - struct directory const *rr = *(struct directory * const *)r; - - if (rr->parent->path_index < ll->parent->path_index) - { - return -1; - } - - if (rr->parent->path_index > ll->parent->path_index) - { - return 1; - } - - return strcmp(rr->self->isorec.name, ll->self->isorec.name); - -} /* compare_paths(... */ - -static int generate_path_tables() -{ - struct directory_entry * de; - struct directory * dpnt; - int fix; - int i; - int j; - int namelen; - char * npnt; - char * npnt1; - int tablesize; - - /* - * First allocate memory for the tables and initialize the memory - */ - tablesize = path_blocks << 11; - path_table_m = (char *) e_malloc(tablesize); - path_table_l = (char *) e_malloc(tablesize); - memset(path_table_l, 0, tablesize); - memset(path_table_m, 0, tablesize); - - /* - * Now start filling in the path tables. Start with root directory - */ - if( next_path_index > 0xffff ) - { - error (1, 0, _("Unable to generate sane path tables - too many directories (%d)\n"), - next_path_index); - } - - path_table_index = 0; - pathlist = (struct directory **) e_malloc(sizeof(struct directory *) - * next_path_index); - memset(pathlist, 0, sizeof(struct directory *) * next_path_index); - build_pathlist(root); - - do - { - fix = 0; -#ifdef __STDC__ - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), - (int (*)(const void *, const void *))compare_paths); -#else - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), - compare_paths); -#endif - - for(j=1; jpath_index != j) - { - pathlist[j]->path_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_name; - - /* - * So the root comes out OK - */ - if( (*npnt == 0) || (dpnt == root) ) - { - npnt = "."; - } - npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { - npnt = npnt1 + 1; - } - - de = dpnt->self; - if(!de) - { - error (1, 0, _("Fatal goof\n")); - } - - - namelen = de->isorec.name_len[0]; - - path_table_l[path_table_index] = namelen; - path_table_m[path_table_index] = namelen; - path_table_index += 2; - - set_731(path_table_l + path_table_index, dpnt->extent); - set_732(path_table_m + path_table_index, dpnt->extent); - path_table_index += 4; - - set_721(path_table_l + path_table_index, - dpnt->parent->path_index); - set_722(path_table_m + path_table_index, - dpnt->parent->path_index); - path_table_index += 2; - - for(i =0; iisorec.name[i]; - path_table_m[path_table_index] = de->isorec.name[i]; - path_table_index++; - } - if(path_table_index & 1) - { - path_table_index++; /* For odd lengths we pad */ - } - } - - free(pathlist); - if(path_table_index != path_table_size) - { - fprintf (stderr, _("Path table lengths do not match %d %d\n"), - path_table_index, - path_table_size); - } - return 0; -} /* generate_path_tables(... */ - -void -FDECL3(memcpy_max, char *, to, char *, from, int, max) -{ - int n = strlen(from); - if (n > max) - { - n = max; - } - memcpy(to, from, n); - -} /* memcpy_max(... */ - -void FDECL1(outputlist_insert, struct output_fragment *, frag) -{ - if( out_tail == NULL ) - { - out_list = out_tail = frag; - } - else - { - out_tail->of_next = frag; - out_tail = frag; - } -} - -static int FDECL1(file_write, FILE *, outfile) -{ - int should_write; - - /* - * OK, all done with that crap. Now write out the directories. - * This is where the fur starts to fly, because we need to keep track of - * each file as we find it and keep track of where we put it. - */ - - should_write = last_extent - session_start; - - if( print_size > 0 ) - { - fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), - last_extent - session_start); - exit (0); - } - if( verbose > 2 ) - { -#ifdef DBG_ISO - fprintf(stderr,"Total directory extents being written = %llu\n", last_extent); -#endif - - fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), - last_extent - session_start); - } - - /* - * Now write all of the files that we need. - */ - write_files(outfile); - - /* - * The rest is just fluff. - */ - if( verbose == 0 ) - { - return 0; - } - - fprintf (stderr, _("Total extents actually written = %llu\n"), - last_extent_written - session_start); - - /* - * Hard links throw us off here - */ - assert (last_extent > session_start); - if(should_write + session_start != last_extent) - { - fprintf (stderr, _("Number of extents written different than what was predicted. Please fix.\n")); - fprintf (stderr, _("Predicted = %d, written = %llu\n"), should_write, last_extent); - } - - fprintf (stderr, _("Total translation table size: %d\n"), table_size); - fprintf (stderr, _("Total rockridge attributes bytes: %d\n"), rockridge_size); - fprintf (stderr, _("Total directory bytes: %d\n"), total_dir_size); - fprintf (stderr, _("Path table size(bytes): %d\n"), path_table_size); - -#ifdef DEBUG - fprintf(stderr, "next extent, last_extent, last_extent_written %d %d %d\n", - next_extent, last_extent, last_extent_written); -#endif - - return 0; - -} /* iso_write(... */ - -char *creation_date = NULL; -char *modification_date = NULL; -char *expiration_date = NULL; -char *effective_date = NULL; - -/* - * Function to write the PVD for the disc. - */ -static int FDECL1(pvd_write, FILE *, outfile) -{ - char iso_time[17]; - int should_write; - struct tm local; - struct tm gmt; - - - time(&begun); - - local = *localtime(&begun); - gmt = *gmtime(&begun); - - /* - * This will break in the year 2000, I supose, but there is no good way - * to get the top two digits of the year. - */ - sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", 1900 + local.tm_year, - local.tm_mon+1, local.tm_mday, - local.tm_hour, local.tm_min, local.tm_sec); - - local.tm_min -= gmt.tm_min; - local.tm_hour -= gmt.tm_hour; - local.tm_yday -= gmt.tm_yday; - iso_time[16] = (local.tm_min + 60*(local.tm_hour + 24*local.tm_yday)) / 15; - - /* - * Next we write out the primary descriptor for the disc - */ - memset(&vol_desc, 0, sizeof(vol_desc)); - vol_desc.type[0] = ISO_VD_PRIMARY; - memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - vol_desc.version[0] = 1; - - memset(vol_desc.system_id, ' ', sizeof(vol_desc.system_id)); - memcpy_max(vol_desc.system_id, system_id, strlen(system_id)); - - memset(vol_desc.volume_id, ' ', sizeof(vol_desc.volume_id)); - memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id)); - - should_write = last_extent - session_start; - set_733((char *) vol_desc.volume_space_size, should_write); - set_723(vol_desc.volume_set_size, volume_set_size); - set_723(vol_desc.volume_sequence_number, volume_sequence_number); - set_723(vol_desc.logical_block_size, 2048); - - /* - * The path tables are used by DOS based machines to cache directory - * locations - */ - - set_733((char *) vol_desc.path_table_size, path_table_size); - set_731(vol_desc.type_l_path_table, path_table[0]); - set_731(vol_desc.opt_type_l_path_table, path_table[1]); - set_732(vol_desc.type_m_path_table, path_table[2]); - set_732(vol_desc.opt_type_m_path_table, path_table[3]); - - /* - * Now we copy the actual root directory record - */ - memcpy(vol_desc.root_directory_record, &root_record, - sizeof(struct iso_directory_record) + 1); - - /* - * The rest is just fluff. It looks nice to fill in many of these fields, - * though. - */ - FILL_SPACE(volume_set_id); - if(volset_id) memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id)); - - FILL_SPACE(publisher_id); - if(publisher) memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher)); - - FILL_SPACE(preparer_id); - if(preparer) memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer)); - - FILL_SPACE(application_id); - if(appid) memcpy_max(vol_desc.application_id, appid, strlen(appid)); - - FILL_SPACE(copyright_file_id); - if(copyright) memcpy_max(vol_desc.copyright_file_id, copyright, - strlen(copyright)); - - FILL_SPACE(abstract_file_id); - if(abstract) memcpy_max(vol_desc.abstract_file_id, abstract, - strlen(abstract)); - - FILL_SPACE(bibliographic_file_id); - if(biblio) memcpy_max(vol_desc.bibliographic_file_id, biblio, - strlen(biblio)); - - FILL_SPACE(creation_date); - FILL_SPACE(modification_date); - FILL_SPACE(expiration_date); - FILL_SPACE(effective_date); - vol_desc.file_structure_version[0] = 1; - FILL_SPACE(application_data); - - memcpy(vol_desc.creation_date, creation_date ? creation_date : iso_time, 17); - memcpy(vol_desc.modification_date, modification_date ? modification_date : iso_time, 17); - memcpy(vol_desc.expiration_date, expiration_date ? expiration_date : "0000000000000000", 17); - memcpy(vol_desc.effective_date, effective_date ? effective_date : iso_time, 17); - - /* - * if not a bootable cd do it the old way - */ - xfwrite(&vol_desc, 1, 2048, outfile); - last_extent_written++; - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(evd_write, FILE *, outfile) -{ - struct iso_primary_descriptor evol_desc; - - /* - * Now write the end volume descriptor. Much simpler than the other one - */ - memset(&evol_desc, 0, sizeof(evol_desc)); - evol_desc.type[0] = ISO_VD_END; - memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - evol_desc.version[0] = 1; - xfwrite(&evol_desc, 1, 2048, outfile); - last_extent_written += 1; - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(pathtab_write, FILE *, outfile) -{ - /* - * Next we write the path tables - */ - xfwrite(path_table_l, 1, path_blocks << 11, outfile); - xfwrite(path_table_m, 1, path_blocks << 11, outfile); - last_extent_written += 2*path_blocks; - free(path_table_l); - free(path_table_m); - path_table_l = NULL; - path_table_m = NULL; - return 0; -} - -static int FDECL1(exten_write, FILE *, outfile) -{ - xfwrite(extension_record, 1, SECTOR_SIZE, outfile); - last_extent_written++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ -int FDECL1(oneblock_size, int, starting_extent) -{ - last_extent++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ - -#define PADBLOCK_SIZE 16 - -static int FDECL1(pathtab_size, int, starting_extent) -{ - path_table[0] = starting_extent; - - path_table[1] = 0; - path_table[2] = path_table[0] + path_blocks; - path_table[3] = 0; - last_extent += 2*path_blocks; - return 0; -} - -static int FDECL1(padblock_size, int, starting_extent) -{ - last_extent += PADBLOCK_SIZE; - return 0; -} - -static int file_gen() -{ - assign_file_addresses(root); - return 0; -} - -static int dirtree_dump() -{ - if (verbose > 2) - { - dump_tree(root); - } - return 0; -} - -static int FDECL1(dirtree_fixup, int, starting_extent) -{ - if (use_RockRidge && reloc_dir) - finish_cl_pl_entries(); - - if (use_RockRidge ) - update_nlink_field(root); - return 0; -} - -static int FDECL1(dirtree_size, int, starting_extent) -{ - assign_directory_addresses(root); - return 0; -} - -static int FDECL1(ext_size, int, starting_extent) -{ - extern int extension_record_size; - struct directory_entry * s_entry; - extension_record_extent = starting_extent; - s_entry = root->contents; - set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 24, - extension_record_extent); - set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 8, - extension_record_size); - last_extent++; - return 0; -} - -static int FDECL1(dirtree_write, FILE *, outfile) -{ - generate_iso9660_directories(root, outfile); - return 0; -} - -static int FDECL1(dirtree_cleanup, FILE *, outfile) -{ - free_directories(root); - return 0; -} - -static int FDECL1(padblock_write, FILE *, outfile) -{ - char *buffer; - - buffer = e_malloc (2048 * PADBLOCK_SIZE); - memset (buffer, 0, 2048 * PADBLOCK_SIZE); - - if (use_embedded_boot) - { - FILE *fp = fopen (boot_image_embed, "rb"); - if (! fp) - error (1, errno, _("Unable to open %s"), boot_image_embed); - - if (fread (buffer, 1, 2048 * PADBLOCK_SIZE, fp) == 0) - error (1, errno, _("cannot read %d bytes from %s"), - 2048 * PADBLOCK_SIZE, boot_image_embed); - if (fgetc (fp) != EOF) - error (1, 0, _("%s is too big for embed area"), boot_image_embed); - } - - if (use_protective_msdos_label) - { - struct msdos_partition_mbr *mbr = (void *) buffer; - - memset (mbr->entries, 0, sizeof(mbr->entries)); - - /* Some idiotic BIOSes refuse to boot if they don't find at least - one partition with active bit set. */ - mbr->entries[0].flag = 0x80; - - /* Doesn't really matter, as long as it's non-zero. It seems that - 0xCD is used elsewhere, so we follow suit. */ - mbr->entries[0].type = 0xcd; - - /* Start immediately (sector 1). */ - mbr->entries[0].start = 1; - - /* We don't know yet. Let's keep it safe. */ - mbr->entries[0].length = UINT32_MAX; - - mbr->signature = MSDOS_PARTITION_SIGNATURE; - } - - xfwrite (buffer, 1, 2048 * PADBLOCK_SIZE, outfile); - last_extent_written += PADBLOCK_SIZE; - - return 0; -} - -struct output_fragment padblock_desc = {NULL, padblock_size, NULL, padblock_write}; -struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write}; -struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write}; -struct output_fragment pathtable_desc = {NULL, pathtab_size, generate_path_tables, pathtab_write}; -struct output_fragment dirtree_desc = {NULL, dirtree_size, NULL, dirtree_write}; -struct output_fragment dirtree_clean = {NULL, dirtree_fixup, dirtree_dump, dirtree_cleanup}; -struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write}; -struct output_fragment files_desc = {NULL, NULL, file_gen, file_write}; From 7fb5c25fd0f02c1b751821915da5d3036f5a5692 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 18 May 2010 11:51:37 +0100 Subject: [PATCH 211/503] * util/grub-mkrescue.in: Sync up with grub-install in terms of how we handle finding grub-mkimage. Default to finding grub-mkimage in ${bindir} with program_transform_name applied, and provide a --grub-mkimage option to override this. --- ChangeLog | 7 +++++++ util/grub-mkrescue.in | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8258400c0..4cfe4c576 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-18 Colin Watson + + * util/grub-mkrescue.in: Sync up with grub-install in terms of how + we handle finding grub-mkimage. Default to finding grub-mkimage in + ${bindir} with program_transform_name applied, and provide a + --grub-mkimage option to override this. + 2010-05-17 Vladimir Serbinenko Remove grub-mkisofs. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 5f35f084a..6018816b3 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -37,6 +37,7 @@ pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi rom_directory= +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage # Print the usage. @@ -50,6 +51,7 @@ Make GRUB rescue image. --output=FILE save output in FILE [required] --modules=MODULES pre-load specified modules MODULES --rom-directory=DIR save rom images in DIR [optional] + --grub-mkimage=FILE use FILE as grub-mkimage $0 generates a bootable rescue image with specified source files or directories. @@ -78,6 +80,8 @@ for option in "$@"; do PATH=${override_dir}:$PATH export PATH ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; -*) echo "Unrecognized option \`$option'" 1>&2 usage @@ -94,6 +98,14 @@ if [ "x${output_image}" = x ] ; then exit 1 fi +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + if test "x$TMP" != x; then MKTEMP_TEMPLATE="$TMP/grub-mkrescue.XXXXXXXXXX" elif test "x$TEMP" != x; then @@ -157,7 +169,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} - grub-mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ + $grub_mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ search iso9660 configfile normal sh memdisk tar $4 rm -rf ${memdisk_img} } @@ -207,7 +219,7 @@ grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${i if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + $grub_mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img From 355b51e9b50174de0254bc97ec7008f70b21855c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 18 May 2010 11:57:31 +0100 Subject: [PATCH 212/503] Fix build with non-GNU libcs. * util/misc.c (canonicalize_file_name): Move to ... * kern/emu/misc.c (canonicalize_file_name): ... here. Needed by grub_make_system_path_relative_to_its_root. --- ChangeLog | 8 ++++++++ kern/emu/misc.c | 13 +++++++++++++ util/misc.c | 13 ------------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cfe4c576..a3050ee07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-05-18 Colin Watson + + Fix build with non-GNU libcs. + + * util/misc.c (canonicalize_file_name): Move to ... + * kern/emu/misc.c (canonicalize_file_name): ... here. Needed by + grub_make_system_path_relative_to_its_root. + 2010-05-18 Colin Watson * util/grub-mkrescue.in: Sync up with grub-install in terms of how diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 4888f4a6b..54c808a47 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -176,6 +176,19 @@ grub_get_rtc (void) * GRUB_TICKS_PER_SECOND / 1000000)); } +char * +canonicalize_file_name (const char *path) +{ + char *ret; +#ifdef PATH_MAX + ret = xmalloc (PATH_MAX); + (void) realpath (path, ret); +#else + ret = realpath (path, NULL); +#endif + return ret; +} + #ifdef __CYGWIN__ /* Convert POSIX path to Win32 path, remove drive letter, replace backslashes. */ diff --git a/util/misc.c b/util/misc.c index 6785eb00f..46e5c6093 100644 --- a/util/misc.c +++ b/util/misc.c @@ -286,19 +286,6 @@ fail: #endif /* __MINGW32__ */ -char * -canonicalize_file_name (const char *path) -{ - char *ret; -#ifdef PATH_MAX - ret = xmalloc (PATH_MAX); - (void) realpath (path, ret); -#else - ret = realpath (path, NULL); -#endif - return ret; -} - #ifdef GRUB_UTIL void grub_util_init_nls (void) From 750067477388b5f74bb3cfd343cb0cfe74de26e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 14:20:00 +0200 Subject: [PATCH 213/503] * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. --- ChangeLog | 4 ++++ po/POTFILES | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 89526d020..bf375bc64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-18 Vladimir Serbinenko + + * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. + 2010-05-18 Colin Watson * configure.ac: Check for Linux device-mapper support. diff --git a/po/POTFILES b/po/POTFILES index 0dfc3c041..d2c579edb 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -77,5 +77,5 @@ normal/misc.c term/serial.c -util/grub-mkrawimage.c +util/grub-mkimage.c util/i386/pc/grub-setup.c From 26966aeba7259cf38d1ede192c7b34f258d470c2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 14:21:15 +0200 Subject: [PATCH 214/503] 2010-05-18 Vladimir Serbinenko * util/grub-mkrescue.in: Remove -O i386-pc duplication. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bf375bc64..8e864dddb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-18 Vladimir Serbinenko + + * util/grub-mkrescue.in: Remove -O i386-pc duplication. + Reported by: Seth Goldberg. + 2010-05-18 Vladimir Serbinenko * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 6018816b3..7e7253006 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -219,7 +219,7 @@ grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${i if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - $grub_mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + $grub_mkimage -O i386-pc -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img From 654e1d1e0e0943348b4283e14a9f03607ee4df56 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 13:45:25 +0200 Subject: [PATCH 215/503] * util/grub-install.in: Add missing "in" keyword. --- ChangeLog | 4 ++++ util/grub-install.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8e864dddb..34e7b76dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-18 Vladimir Serbinenko + + * util/grub-install.in: Add missing "in" keyword. + 2010-05-18 Vladimir Serbinenko * util/grub-mkrescue.in: Remove -O i386-pc duplication. diff --git a/util/grub-install.in b/util/grub-install.in index 8a93ace8c..0db216fd5 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -342,7 +342,7 @@ else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi -case "${target_cpu}-${platform}" +case "${target_cpu}-${platform}" in i386-pc) mkimage_target=i386-pc ;; sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; From 01b8d2d7870c81d9e6151b3d2f3a936633db296d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 13:55:26 +0200 Subject: [PATCH 216/503] * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with -DGRUB_PKGLIBROOTDIR= and prepend @PACKAGE_TARNAME@. All users updated. * util/grub-mkimage.c (image_targets): Add i386-multiboot. (main): Add a slash after pkglibdirroot. --- ChangeLog | 7 +++++++ Makefile.in | 2 +- util/grub-mkimage.c | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34e7b76dd..2ce1c23e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-18 Vladimir Serbinenko + + * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with + -DGRUB_PKGLIBROOTDIR= and prepend @PACKAGE_TARNAME@. All users updated. + * util/grub-mkimage.c (image_targets): Add i386-multiboot. + (main): Add a slash after pkglibdirroot. + 2010-05-18 Vladimir Serbinenko * util/grub-install.in: Add missing "in" keyword. diff --git a/Makefile.in b/Makefile.in index 26a494518..75388e3c8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ - -DGRUB_LIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" + -DGRUB_PKGLIBROOTDIR=\"$(libdir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index cc4a225d4..6366a9803 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -99,6 +99,28 @@ struct image_target_desc image_targets[] = .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, + { + .name = "i386-multiboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, { .name = "i386-pc", .voidp_sizeof = 4, @@ -1182,7 +1204,7 @@ Make a bootable image of GRUB.\n\ \n\ Report bugs to <%s>.\n\ "), - program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, + program_name, GRUB_PKGLIBROOTDIR, DEFAULT_DIRECTORY, formats, PACKAGE_BUGREPORT); free (formats); @@ -1320,14 +1342,16 @@ main (int argc, char *argv[]) last = strchr (last + 1, '-'); if (!last) last = image_target->name + strlen (image_target->name); - dir = xmalloc (sizeof (GRUB_LIBDIR) + (last - image_target->name)); - memcpy (dir, GRUB_LIBDIR, sizeof (GRUB_LIBDIR) - 1); - memcpy (dir + sizeof (GRUB_LIBDIR) - 1, image_target->name, + dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name) + + 1); + memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1); + *(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/'; + memcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->name, last - image_target->name); - *(dir + sizeof (GRUB_LIBDIR) - 1 + (last - image_target->name)) = 0; + *(dir + sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name)) = 0; } - generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, + generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, image_target, note); From 95b97950e274dc18c16003cd9d5f552c989156a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 14:00:51 +0200 Subject: [PATCH 217/503] * include/grub/i18n.h (gettext): Inline instead of using #define. (grub_gettext): Likewise. (_): Likewise. --- ChangeLog | 6 ++++++ include/grub/i18n.h | 24 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ce1c23e3..4e0f35c1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-18 Vladimir Serbinenko + + * include/grub/i18n.h (gettext): Inline instead of using #define. + (grub_gettext): Likewise. + (_): Likewise. + 2010-05-18 Vladimir Serbinenko * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 9e7f52d45..57ca1c45b 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -42,17 +42,33 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # ifdef GRUB_UTIL -# define gettext(Msgid) ((const char *) (Msgid)) +static inline const char * __attribute__ ((always_inline)) +gettext (const char *str) +{ + return str; +} # else -# define grub_gettext(str) ((const char *) (str)) +static inline const char * __attribute__ ((always_inline)) +grub_gettext (const char *str) +{ + return str; +} # endif /* GRUB_UTIL */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ #ifdef GRUB_UTIL -# define _(str) gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return gettext(str); +} #else -# define _(str) grub_gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return grub_gettext(str); +} #endif /* GRUB_UTIL */ #define N_(str) str From 4db50964ad0e96ce4bae73d589160a4b9bd0bd44 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 18 May 2010 13:01:59 +0100 Subject: [PATCH 218/503] Add btrfs probing support, currently only in the single-device case. * kern/emu/getroot.c (find_root_device_from_mountinfo): New function. (grub_guess_root_device): Call find_root_device_from_mountinfo before looking in /dev. --- ChangeLog.btrfs-probe | 8 +++++ kern/emu/getroot.c | 84 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 ChangeLog.btrfs-probe diff --git a/ChangeLog.btrfs-probe b/ChangeLog.btrfs-probe new file mode 100644 index 000000000..77c9995c8 --- /dev/null +++ b/ChangeLog.btrfs-probe @@ -0,0 +1,8 @@ +2010-05-18 Colin Watson + + Add btrfs probing support, currently only in the single-device case. + + * kern/emu/getroot.c (find_root_device_from_mountinfo): New + function. + (grub_guess_root_device): Call find_root_device_from_mountinfo + before looking in /dev. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6875044da..da62089fa 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -80,6 +80,84 @@ xgetcwd (void) return path; } +#ifdef __linux__ + +/* Statting something on a btrfs filesystem always returns a virtual device + major/minor pair rather than the real underlying device, because btrfs + can span multiple underlying devices (and even if it's currently only + using a single device it can be dynamically extended onto another). We + can't deal with the multiple-device case yet, but in the meantime, we can + at least cope with the single-device case by scanning + /proc/self/mountinfo. */ +static char * +find_root_device_from_mountinfo (const char *dir) +{ + FILE *fp; + char buf[1024]; /* XXX */ + char *ret = NULL; + + fp = fopen ("/proc/self/mountinfo", "r"); + if (! fp) + return NULL; /* fall through to other methods */ + + while (fgets (buf, sizeof (buf), fp)) + { + int mnt_id, parent_mnt_id; + unsigned int major, minor; + char enc_root[PATH_MAX], enc_path[PATH_MAX]; + int count; + size_t enc_path_len; + const char *sep; + char fstype[PATH_MAX], device[PATH_MAX]; + struct stat st; + + if (sscanf (buf, "%d %d %u:%u %s %s%n", + &mnt_id, &parent_mnt_id, &major, &minor, enc_root, enc_path, + &count) < 6) + continue; + + if (strcmp (enc_root, "/") != 0) + continue; /* only a subtree is mounted */ + + enc_path_len = strlen (enc_path); + if (strncmp (dir, enc_path, enc_path_len) != 0 || + (dir[enc_path_len] && dir[enc_path_len] != '/')) + continue; + + /* This is a parent of the requested directory. /proc/self/mountinfo + is in mount order, so it must be the closest parent we've + encountered so far. If it's virtual, return its device node; + otherwise, carry on to try to find something closer. */ + + free (ret); + ret = NULL; + + if (major != 0) + continue; /* not a virtual device */ + + sep = strstr (buf + count, " - "); + if (!sep) + continue; + + sep += strlen (" - "); + if (sscanf (sep, "%s %s", fstype, device) != 2) + continue; + + if (stat (device, &st) < 0) + continue; + + if (!S_ISBLK (st.st_mode)) + continue; /* not a block device */ + + ret = strdup (device); + } + + fclose (fp); + return ret; +} + +#endif /* __linux__ */ + #ifdef __MINGW32__ static char * @@ -355,6 +433,12 @@ grub_guess_root_device (const char *dir) #else /* !__GNU__ */ struct stat st; +#ifdef __linux__ + os_dev = find_root_device_from_mountinfo (dir); + if (os_dev) + return os_dev; +#endif /* __linux__ */ + if (stat (dir, &st) < 0) grub_util_error ("cannot stat `%s'", dir); From c4f7b5235917d65f43310c3e0ae895ebfcc663ca Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 18 May 2010 20:10:37 +0200 Subject: [PATCH 219/503] 2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only gnumach and gnumach.gz. --- ChangeLog | 5 +++++ util/grub.d/10_hurd.in | 39 +++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4e0f35c1d..e8bb242bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> + + * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only + gnumach and gnumach.gz. + 2010-05-18 Vladimir Serbinenko * include/grub/i18n.h (gettext): Inline instead of using #define. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 8e16e7d9f..e446f10e8 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -35,13 +35,13 @@ all_of_them=true # FIXME: add l4 here? kernel= -for i in /boot/gnumach.gz /boot/gnumach ; do +for i in /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} + kernels="${kernels} ${rel_dirname}/${basename}" at_least_one=true fi done @@ -71,17 +71,22 @@ if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else exit 1 fi -cat << EOF -menuentry "${OS}" ${CLASS} { +for kernel in ${kernels} +do + kernel_base="`basename "${kernel}"`" + KERNEL="using ${kernel_base}" + + cat << EOF +menuentry "${OS} ${KERNEL}" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -93,17 +98,17 @@ cat << EOF } EOF -cat << EOF -menuentry "${OS} (recovery mode)" { + cat << EOF +menuentry "${OS} ${KERNEL} (recovery mode)" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -114,3 +119,5 @@ cat << EOF module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' } EOF + +done From 74276c0df7489cf122c9cc16109291086483f8f3 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Tue, 18 May 2010 21:58:49 +0200 Subject: [PATCH 220/503] * util/grub.d/10_windows.in: Use path names instead of drive letters to prevent warning from Cygwin 1.7. Add drivemap command to menuentry if needed. --- ChangeLog | 6 ++++++ util/grub.d/10_windows.in | 21 +++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8bb242bf..46d9e7c34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-18 Christian Franke + + * util/grub.d/10_windows.in: Use path names instead of + drive letters to prevent warning from Cygwin 1.7. + Add drivemap command to menuentry if needed. + 2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 35dd4a4cc..7d221eac9 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2008 Free Software Foundation, Inc. +# Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,8 +28,8 @@ esac # Try C: even if current system is on other partition. case "$SYSTEMDRIVE" in - [Cc]:) dirlist="C:" ;; - [D-Zd-z]:) dirlist="C: $SYSTEMDRIVE" ;; + [Cc]:) drives="C:" ;; + [D-Zd-z]:) drives="C: $SYSTEMDRIVE" ;; *) exit 0 ;; esac @@ -51,7 +51,13 @@ get_os_name_from_boot_ini () } -for dir in $dirlist ; do +for drv in $drives ; do + + # Convert to Cygwin path. + dir=`cygpath "$drv"` + test -n "$dir" || continue + + needmap= # Check for Vista bootmgr. if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then @@ -60,6 +66,7 @@ for dir in $dirlist ; do # 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" + needmap=t else continue @@ -68,14 +75,16 @@ for dir in $dirlist ; do # Get boot /dev/ice. dev=`${grub_probe} -t device "$dir" 2>/dev/null` || continue - echo "Found $OS on $dir ($dev)" >&2 + echo "Found $OS on $drv ($dev)" >&2 cat << EOF menuentry "$OS" { EOF save_default_entry | sed -e 's,^,\t,' prepare_grub_to_access_device "$dev" | sed 's,^,\t,' - + test -z "$needmap" || cat < Date: Wed, 19 May 2010 10:15:48 +0530 Subject: [PATCH 221/503] allocate memory in sizes of two powers --- script/argv.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/script/argv.c b/script/argv.c index 1ac81f4b8..4974178cc 100644 --- a/script/argv.c +++ b/script/argv.c @@ -20,8 +20,23 @@ #include #include -#define ARG_ALLOCATION_UNIT (32 * sizeof (char)) -#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*)) +static unsigned +round_up_exp (unsigned v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + if (sizeof (v) > 4) + v |= v >> 32; + + v++; + v += (v == 0); + + return v; +} void grub_script_argv_free (struct grub_script_argv *argv) @@ -48,7 +63,7 @@ grub_script_argv_next (struct grub_script_argv *argv) if (argv->argc == 0) { - p = grub_malloc (ALIGN_UP (2 * sizeof (char *), ARG_ALLOCATION_UNIT)); + p = grub_malloc (2 * sizeof (char *)); if (! p) return 1; @@ -62,8 +77,7 @@ grub_script_argv_next (struct grub_script_argv *argv) if (! argv->args[argv->argc - 1]) return 0; - p = grub_realloc (p, ALIGN_UP ((argv->argc + 1) * sizeof (char *), - ARG_ALLOCATION_UNIT)); + p = grub_realloc (p, round_up_exp ((argv->argc + 1) * sizeof (char *))); if (! p) return 1; @@ -86,8 +100,7 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s) a = p ? grub_strlen (p) : 0; b = grub_strlen (s); - p = grub_realloc (p, ALIGN_UP ((a + b + 1) * sizeof (char), - ARG_ALLOCATION_UNIT)); + p = grub_realloc (p, round_up_exp ((a + b + 1) * sizeof (char))); if (! p) return 1; From 0003008a588020db005454a02b5a192b93254e88 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 19 May 2010 10:25:41 +0530 Subject: [PATCH 222/503] memory leak fix in grub_script_execute_cmdline --- include/grub/script_sh.h | 2 +- script/argv.c | 3 ++- script/execute.c | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 5455fc763..9199a539e 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -66,7 +66,7 @@ struct grub_script_arg /* An argument vector. */ struct grub_script_argv { - int argc; + unsigned argc; char **args; }; diff --git a/script/argv.c b/script/argv.c index 4974178cc..56274f263 100644 --- a/script/argv.c +++ b/script/argv.c @@ -29,6 +29,7 @@ round_up_exp (unsigned v) v |= v >> 4; v |= v >> 8; v |= v >> 16; + if (sizeof (v) > 4) v |= v >> 32; @@ -41,7 +42,7 @@ round_up_exp (unsigned v) void grub_script_argv_free (struct grub_script_argv *argv) { - int i; + unsigned i; if (argv->args) { diff --git a/script/execute.c b/script/execute.c index 2040be13c..6a755a040 100644 --- a/script/execute.c +++ b/script/execute.c @@ -77,7 +77,7 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) } else if (grub_strcmp (name, "*") == 0) { - int i; + unsigned i; for (i = 0; ! errors && i < scope->argv.argc; i++) if (type == GRUB_SCRIPT_ARG_TYPE_VAR) @@ -97,7 +97,7 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) } else if (grub_strcmp (name, "@") == 0) { - int i; + unsigned i; for (i = 0; ! errors && i < scope->argv.argc; i++) { @@ -287,6 +287,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); grub_env_set ("?", errnobuf); + grub_script_argv_free (&argv); grub_print_error (); return 0; @@ -353,8 +354,8 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd) grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd) { - int i; - int result; + unsigned i; + grub_err_t result; struct grub_script_argv argv; struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; From 123b7a8571689a1227f18102546b4a1413f275d7 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 19 May 2010 14:31:43 +0530 Subject: [PATCH 223/503] Fix grub-mkrescue usage unit testing. * tests/util/grub-shell.in: Use --grub-mkimage with grub-mkrescue. --- ChangeLog | 6 ++++++ tests/util/grub-shell.in | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 46d9e7c34..53a664d2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-19 BVK Chaitanya + + Fix grub-mkrescue usage unit testing. + + * tests/util/grub-shell.in: Use --grub-mkimage with grub-mkrescue. + 2010-05-18 Christian Franke * util/grub.d/10_windows.in: Use path names instead of diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index a41a6f6f4..17da6c8c0 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -124,7 +124,8 @@ halt EOF isofile=`mktemp` -grub-mkrescue --output=${isofile} --override-directory=${builddir} \ +grub-mkrescue --grub-mkimage=${builddir}/grub-mkimage --output=${isofile} \ + --override-directory=${builddir} \ /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \ >/dev/null 2>&1 From fa9d256ee45ed71ab9fc02809a0927d740adca86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Thu, 20 May 2010 02:05:43 +0200 Subject: [PATCH 224/503] Fix merge error in NetBSD code. --- ChangeLog | 6 ++++++ kern/emu/hostdisk.c | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53a664d2f..1348c91c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-20 Grégoire Sutre + + * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]: + Fix merge error in NetBSD code. + (find_partition_start) [__NetBSD__]: Likewise. + 2010-05-19 BVK Chaitanya Fix grub-mkrescue usage unit testing. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 0ab25ec7d..9c4697552 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -412,7 +412,8 @@ devmapper_fail: fd = open (dev, O_RDONLY); if (fd == -1) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot open `%s' while attempting to get disk geometry", dev); return 0; } @@ -434,9 +435,6 @@ devmapper_fail: # if !defined(__NetBSD__) return hdg.start; # else /* defined(__NetBSD__) */ - /* Since dev and convert_system_partition_to_system_disk (dev) are - * different, we know that dev is of the form /dev/r[wsc]d[0-9]+[a-z] - * and in particular it cannot be a floppy device. */ index = dev[strlen(dev) - 1] - 'a'; if (index >= label.d_npartitions) @@ -1433,7 +1431,6 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] * and in particular it cannot be a floppy device. */ - index = os_dev[strlen(os_dev) - 1] - 'a'; # endif /* !defined(__NetBSD__) */ start = find_partition_start (os_dev); From 96779aec8ee4e7edfcb1a09a279db528f6ae8f5e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 20 May 2010 23:16:10 +0100 Subject: [PATCH 225/503] * util/misc.c: Move inclusion of to ... * kern/emu/misc.c: ... here. Needed for canonicalize_file_name. --- ChangeLog | 5 +++++ kern/emu/misc.c | 3 +++ util/misc.c | 3 --- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1348c91c6..42b04d1c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-20 Colin Watson + + * util/misc.c: Move inclusion of to ... + * kern/emu/misc.c: ... here. Needed for canonicalize_file_name. + 2010-05-20 Grégoire Sutre * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]: diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 54c808a47..a3ccb3076 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -9,6 +9,9 @@ #include #include #include +#ifdef HAVE_LIMITS_H +#include +#endif #include #include diff --git a/util/misc.c b/util/misc.c index 46e5c6093..91bc25a55 100644 --- a/util/misc.c +++ b/util/misc.c @@ -30,9 +30,6 @@ #include #include #include -#ifdef HAVE_LIMITS_H -#include -#endif #include #include From c0f48e654daf3cc9451c267450ab4b617277baf0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 20 May 2010 23:27:15 +0100 Subject: [PATCH 226/503] * util/grub-mkrelpath.c (usage): Remove excess apostrophe. --- ChangeLog | 4 ++++ util/grub-mkrelpath.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 42b04d1c9..cdff463e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-20 Colin Watson + + * util/grub-mkrelpath.c (usage): Remove excess apostrophe. + 2010-05-20 Colin Watson * util/misc.c: Move inclusion of to ... diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index e771bd873..eccb49cdc 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -41,7 +41,7 @@ usage (int status) printf ("\ Usage: %s [OPTIONS] PATH\n\ \n\ -Make a system path relative to it's root.\n\ +Make a system path relative to its root.\n\ \n\ Options:\n\ -h, --help display this message and exit\n\ From f532a574a6b4bd9feb6f17fac74ea64e6244a079 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 21 May 2010 15:34:36 +0530 Subject: [PATCH 227/503] write overflow bug fix with cleanup --- script/argv.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/script/argv.c b/script/argv.c index 56274f263..69322779d 100644 --- a/script/argv.c +++ b/script/argv.c @@ -62,28 +62,18 @@ grub_script_argv_next (struct grub_script_argv *argv) { char **p = argv->args; - if (argv->argc == 0) - { - p = grub_malloc (2 * sizeof (char *)); - if (! p) - return 1; - - argv->argc = 1; - argv->args = p; - argv->args[0] = 0; - argv->args[1] = 0; - return 0; - } - - if (! argv->args[argv->argc - 1]) + if (argv->args && argv->args[argv->argc - 1] == 0) return 0; - p = grub_realloc (p, round_up_exp ((argv->argc + 1) * sizeof (char *))); + p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *))); if (! p) return 1; argv->argc++; argv->args = p; + + if (argv->argc == 1) + argv->args[0] = 0; argv->args[argv->argc] = 0; return 0; } From 1702fbc15de595722b8f1c03181ccbaf364a1337 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 21 May 2010 15:43:24 +0530 Subject: [PATCH 228/503] replace error handling with goto --- script/execute.c | 117 +++++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 50 deletions(-) diff --git a/script/execute.c b/script/execute.c index 6a755a040..4a3f249b0 100644 --- a/script/execute.c +++ b/script/execute.c @@ -51,65 +51,77 @@ grub_env_special (const char *name) static char ** grub_script_env_get (const char *name, grub_script_arg_type_t type) { - int errors = 0; struct grub_script_argv result = { 0, 0 }; - errors += grub_script_argv_next (&result); + if (grub_script_argv_next (&result)) + goto fail; + if (! grub_env_special (name)) { char *v = grub_env_get (name); if (v && v[0]) { if (type == GRUB_SCRIPT_ARG_TYPE_VAR) - errors += grub_script_argv_split_append (&result, v); + { + if (grub_script_argv_split_append (&result, v)) + goto fail; + } else - errors += grub_script_argv_append (&result, v); + if (grub_script_argv_append (&result, v)) + goto fail; } } else if (! scope) - errors += grub_script_argv_append (&result, 0); - + { + if (grub_script_argv_append (&result, 0)) + goto fail; + } else if (grub_strcmp (name, "#") == 0) { char buffer[ERRNO_DIGITS_MAX + 1]; grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc); - errors += grub_script_argv_append (&result, buffer); + if (grub_script_argv_append (&result, buffer)) + goto fail; } else if (grub_strcmp (name, "*") == 0) { unsigned i; - for (i = 0; ! errors && i < scope->argv.argc; i++) + for (i = 0; i < scope->argv.argc; i++) if (type == GRUB_SCRIPT_ARG_TYPE_VAR) { - if (i != 0) - errors += grub_script_argv_next (&result); - errors += grub_script_argv_split_append (&result, - scope->argv.args[i]); + if (i != 0 && grub_script_argv_next (&result)) + goto fail; + + if (grub_script_argv_split_append (&result, scope->argv.args[i])) + goto fail; } else { - if (i != 0) - errors += grub_script_argv_append (&result, " "); - errors += grub_script_argv_append (&result, - scope->argv.args[i]); + if (i != 0 && grub_script_argv_append (&result, " ")) + goto fail; + + if (grub_script_argv_append (&result, scope->argv.args[i])) + goto fail; } } else if (grub_strcmp (name, "@") == 0) { unsigned i; - for (i = 0; ! errors && i < scope->argv.argc; i++) + for (i = 0; i < scope->argv.argc; i++) { - if (i != 0) - errors += grub_script_argv_next (&result); + if (i != 0 && grub_script_argv_next (&result)) + goto fail; if (type == GRUB_SCRIPT_ARG_TYPE_VAR) - errors += grub_script_argv_split_append (&result, - scope->argv.args[i]); + { + if (grub_script_argv_split_append (&result, scope->argv.args[i])) + goto fail; + } else - errors += grub_script_argv_append (&result, - scope->argv.args[i]); + if (grub_script_argv_append (&result, scope->argv.args[i])) + goto fail; } } else @@ -121,21 +133,23 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) else if (num <= scope->argv.argc) { if (type == GRUB_SCRIPT_ARG_TYPE_VAR) - errors += grub_script_argv_split_append (&result, - scope->argv.args[num - 1]); + { + if (grub_script_argv_split_append (&result, + scope->argv.args[num - 1])) + goto fail; + } else - errors += grub_script_argv_append (&result, - scope->argv.args[num - 1]); + if (grub_script_argv_append (&result, scope->argv.args[num - 1])) + goto fail; } } - if (errors) - { - grub_script_argv_free (&result); - return 0; - } - return result.args; + + fail: + + grub_script_argv_free (&result); + return 0; } static grub_err_t @@ -153,21 +167,18 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, struct grub_script_argv *argv) { int i; - int error = 0; char **values = 0; struct grub_script_arg *arg = 0; struct grub_script_argv result = { 0, 0 }; - for (; error == 0 && arglist && arglist->arg; arglist = arglist->next) + for (; arglist && arglist->arg; arglist = arglist->next) { - error += grub_script_argv_next (&result); + if (grub_script_argv_next (&result)) + goto fail; arg = arglist->arg; while (arg) { - if (error) - break; - switch (arg->type) { case GRUB_SCRIPT_ARG_TYPE_VAR: @@ -175,35 +186,41 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, values = grub_script_env_get (arg->str, arg->type); for (i = 0; values && values[i]; i++) { - if (i != 0) - error += grub_script_argv_next (&result); - error += grub_script_argv_append (&result, values[i]); + if (i != 0 && grub_script_argv_next (&result)) + goto fail; + + if (grub_script_argv_append (&result, values[i])) + goto fail; } grub_free (values); break; case GRUB_SCRIPT_ARG_TYPE_TEXT: - if (grub_strlen (arg->str)) - error += grub_script_argv_append (&result, arg->str); + if (grub_strlen (arg->str) && + grub_script_argv_append (&result, arg->str)) + goto fail; break; case GRUB_SCRIPT_ARG_TYPE_DQSTR: case GRUB_SCRIPT_ARG_TYPE_SQSTR: - error += grub_script_argv_append (&result, arg->str); + if (grub_script_argv_append (&result, arg->str)) + goto fail; break; } arg = arg->next; } } - if (error) - return 1; - if (! result.args[result.argc - 1]) result.argc--; *argv = result; return 0; + + fail: + + grub_script_argv_free (&result); + return 1; } static grub_err_t @@ -356,7 +373,7 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) { unsigned i; grub_err_t result; - struct grub_script_argv argv; + struct grub_script_argv argv = { 0, 0 }; struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; if (grub_script_arglist_to_argv (cmdfor->words, &argv)) @@ -398,7 +415,7 @@ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd) { struct grub_script_cmd_menuentry *cmd_menuentry; - struct grub_script_argv argv = {0, 0}; + struct grub_script_argv argv = { 0, 0 }; cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd; From 21717c8fcaa20b66568b90a296c86b99626b034b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 21 May 2010 14:17:15 +0100 Subject: [PATCH 229/503] * util/grub-mkconfig.in: Fix handling of -o so that it works when not the first option. --- ChangeLog | 5 +++++ util/grub-mkconfig.in | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdff463e4..02503a90f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Colin Watson + + * util/grub-mkconfig.in: Fix handling of -o so that it works when + not the first option. + 2010-05-20 Colin Watson * util/grub-mkrelpath.c (usage): Remove excess apostrophe. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 85212f8fc..d1abfa36a 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -50,7 +50,13 @@ EOF } # Check the arguments. +next_grub_cfg=false for option in "$@"; do + if $next_grub_cfg; then + grub_cfg=$option + next_grub_cfg=false + continue + fi case "$option" in -h | --help) usage @@ -59,8 +65,7 @@ for option in "$@"; do echo "$0 (GNU GRUB ${package_version})" exit 0 ;; -o) - shift - grub_cfg=$1 + next_grub_cfg=: ;; --output=*) grub_cfg=`echo "$option" | sed 's/--output=//'` @@ -72,6 +77,11 @@ for option in "$@"; do ;; esac done +if $next_grub_cfg; then + echo "Missing argument to \`-o'" 1>&2 + usage + exit 1 +fi . ${libdir}/grub/grub-mkconfig_lib From 19dcc4908662fcdaa1a69ccbb8b5b2bf7d481f2f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 19:45:14 +0200 Subject: [PATCH 230/503] xen configuration preliminary support based on enhanced version of a kludge I use --- conf/common.rmk | 3 + util/grub-mkconfig.in | 2 + util/grub.d/20_linux_xen.in | 139 ++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 util/grub.d/20_linux_xen.in diff --git a/conf/common.rmk b/conf/common.rmk index beee25be9..641a2c62a 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -219,6 +219,9 @@ grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom ifneq (, $(host_kernel)) grub-mkconfig_SCRIPTS += 10_$(host_kernel) endif +ifeq (linux, $(host_kernel)) +grub-mkconfig_SCRIPTS += 20_linux_xen +endif CLEANFILES += $(grub-mkconfig_SCRIPTS) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 85212f8fc..17b7f7e38 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -239,6 +239,8 @@ export GRUB_DEFAULT \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ + GRUB_CMDLINE_XEN \ + GRUB_CMDLINE_XEN_DEFAULT \ GRUB_CMDLINE_NETBSD \ GRUB_CMDLINE_NETBSD_DEFAULT \ GRUB_TERMINAL_INPUT \ diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in new file mode 100644 index 000000000..862f43888 --- /dev/null +++ b/util/grub.d/20_linux_xen.in @@ -0,0 +1,139 @@ +#! /bin/sh -e + +# grub-mkconfig helper script. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU 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@ +bindir=@bindir@ +libdir=@libdir@ +. ${libdir}/grub/grub-mkconfig_lib + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR=@localedir@ + +CLASS="--class gnu-linux --class gnu --class os --class xen" + +if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS=GNU/Linux +else + OS="${GRUB_DISTRIBUTOR} GNU/Linux" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}" +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 + +linux_entry () +{ + os="$1" + version="$2" + xen_version="$3" + recovery="$4" + args="$5" + xen_args="$6" + if ${recovery} ; then + title="$(gettext_quoted "%s, with Linux %s and XEN %s (recovery mode)")" + else + title="$(gettext_quoted "%s, with Linux %s and XEN %s")" + fi + printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" "${xen_version}" + save_default_entry | sed -e "s/^/\t/" + + if [ -z "${prepare_boot_cache}" ]; then + prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" + fi + printf '%s\n' "${prepare_boot_cache}" + cat << EOF + echo '$(printf "$(gettext_quoted "Loading Linux %s ...")" ${version})' + multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} + module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} +EOF + if test -n "${initrd}" ; then + cat << EOF + echo '$(gettext_quoted "Loading initial ramdisk ...")' + module ${rel_dirname}/${initrd} +EOF + fi + cat << EOF +} +EOF +} + +linux_list=`for i in /boot/vmlinu[xz]-*jeremy* /vmlinu[xz]-*jeremy* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` +xen_list=`for i in /boot/xen*; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` +prepare_boot_cache= + +while [ "x${xen_list}" != "x" ] ; do + list="${linux_list}" + current_xen=`version_find_latest $xen_list` + xen_basename=`basename ${current_xen}` + xen_dirname=`dirname ${current_xen}` + rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname` + xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"` + while [ "x$list" != "x" ] ; do + linux=`version_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-${version}" "initrd.img-${alt_version}" \ + "initrd-${alt_version}.img" "initrd-${alt_version}"; 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 + + linux_entry "${OS}" "${version}" "${xen_version}" false \ + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" + if [ "x${GRUB_DISABLE_LINUX_RECOVERY}" != "xtrue" ]; then + linux_entry "${OS}" "${version}" "${xen_version}" true \ + "single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}" + fi + + list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` + done + xen_list=`echo $xen_list | tr ' ' '\n' | grep -vx $current_xen | tr '\n' ' '` +done From 228cfa97caf0a0c907c945bc307f07029439d629 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:08:48 +0200 Subject: [PATCH 231/503] * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old partition naming style. --- ChangeLog | 5 +++++ kern/i386/pc/init.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02503a90f..090cd645d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Vladimir Serbinenko + + * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old + partition naming style. + 2010-05-21 Colin Watson * util/grub-mkconfig.in: Fix handling of -o so that it works when diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index fa646df19..d81b1e117 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -75,8 +75,8 @@ make_install_device (void) ptr += grub_strlen (ptr); if (grub_install_bsd_part >= 0) - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c", - grub_install_bsd_part + 'a'); + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u", + grub_install_bsd_part + 1); ptr += grub_strlen (ptr); } From 39fbb79aa15e66e4516588bb2f74c1052218d8e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:12:41 +0200 Subject: [PATCH 232/503] * include/grub/i18n.h: Always enable grub_gettext. --- ChangeLog | 4 ++++ include/grub/i18n.h | 14 +++----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 090cd645d..081ea4a1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-21 Vladimir Serbinenko + + * include/grub/i18n.h: Always enable grub_gettext. + 2010-05-21 Vladimir Serbinenko * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 57ca1c45b..a91d73346 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -22,10 +22,10 @@ #include #include -extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); - /* NLS can be disabled through the configure --disable-nls option. */ -#if (defined(ENABLE_NLS) && ENABLE_NLS) +#if (defined(ENABLE_NLS) && ENABLE_NLS) || !defined (GRUB_UTIL) + +extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); # ifdef GRUB_UTIL @@ -41,19 +41,11 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ -# ifdef GRUB_UTIL static inline const char * __attribute__ ((always_inline)) gettext (const char *str) { return str; } -# else -static inline const char * __attribute__ ((always_inline)) -grub_gettext (const char *str) -{ - return str; -} -# endif /* GRUB_UTIL */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ From 9a25f885d3f9aaa8b4725e5fb3fbc4d410b0c39f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:22:29 +0200 Subject: [PATCH 233/503] * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry before calling BIOS. --- ChangeLog | 5 +++++ kern/i386/pc/mmap.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 081ea4a1d..02d16e835 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Vladimir Serbinenko + + * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry + before calling BIOS. + 2010-05-21 Vladimir Serbinenko * include/grub/i18n.h: Always enable grub_gettext. diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c index 52d8fd597..72a6b3539 100644 --- a/kern/i386/pc/mmap.c +++ b/kern/i386/pc/mmap.c @@ -20,6 +20,7 @@ #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)) @@ -28,6 +29,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin struct grub_machine_mmap_entry *entry = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (entry, 0, sizeof (entry)); + /* Check if grub_get_mmap_entry works. */ cont = grub_get_mmap_entry (entry, 0); @@ -43,6 +46,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin if (! cont) break; + grub_memset (entry, 0, sizeof (entry)); + cont = grub_get_mmap_entry (entry, cont); } while (entry->size); From a7208779c3f5260f2cb353b047bdece889906600 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 May 2010 23:06:47 +0200 Subject: [PATCH 234/503] init PCI DMA and USB controllers --- kern/mips/yeeloong/init.c | 54 +++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 697e9733c..826659968 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -66,6 +66,49 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, return GRUB_ERR_NONE; } +static void +init_pci (void) +{ + auto int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid); + int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; + /* FIXME: autoscan for BARs and devices. */ + switch (pciid) + { + case 0x00351033: + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0x5025000); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write (addr, 0x2100146); + break; + case 0x00e01033: + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0x5026000); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write (addr, 0x2100146); + break; + } + return 0; + } + + *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) = 0x8000000c; + *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff; + + /* Setup PCI controller. */ + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_COMMAND)) = 0x22b00046; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_CACHELINE)) = 0xff; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_ADDRESS_REG0)) + = 0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 | GRUB_PCI_ADDR_MEM_PREFETCH; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_ADDRESS_REG1)) = 0; + + grub_pci_iterate (set_card); +} + void grub_machine_init (void) { @@ -123,16 +166,7 @@ grub_machine_init (void) grub_cs5536_init_geode (dev); - /* Setup PCI controller. */ - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_COMMAND)) = 0x22b00046; - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_CACHELINE)) = 0xff; - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_ADDRESS_REG0)) - = 0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 | GRUB_PCI_ADDR_MEM_PREFETCH; - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_ADDRESS_REG1)) = 0; + init_pci (); } modend = grub_modules_get_end (); From 6e198650e987488632ff81c2bc538bf5ea299fcf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 May 2010 23:36:44 +0200 Subject: [PATCH 235/503] Enable serial in simulcast with local terminal on yeeloong --- conf/mips-qemu-mips.rmk | 6 ++++++ conf/mips.rmk | 6 ------ kern/mips/yeeloong/init.c | 5 +++++ term/serial.c | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index 2f80ab2e3..0d81bbe8b 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -20,3 +20,9 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_FORMAT = binary + +# For serial.mod. +pkglib_MODULES += serial.mod +serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/mips.rmk b/conf/mips.rmk index 7d30f55f1..26c516fc4 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -10,12 +10,6 @@ kernel_img_HEADERS += cpu/cache.h sbin_SCRIPTS = bin_SCRIPTS = -# For serial.mod. -pkglib_MODULES += serial.mod -serial_mod_SOURCES = term/serial.c -serial_mod_CFLAGS = $(COMMON_CFLAGS) -serial_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For relocator.mod. pkglib_MODULES += relocator.mod relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 826659968..78586dbd4 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -37,6 +37,8 @@ extern void grub_bitmap_init (void); extern void grub_font_init (void); extern void grub_gfxterm_init (void); extern void grub_at_keyboard_init (void); +extern void grub_serial_init (void); +extern void grub_terminfo_init (void); /* FIXME: use interrupt to count high. */ grub_uint64_t @@ -183,6 +185,9 @@ grub_machine_init (void) grub_gfxterm_init (); grub_at_keyboard_init (); + + grub_terminfo_init (); + grub_serial_init (); } void diff --git a/term/serial.c b/term/serial.c index b16b608f1..ef9efac2e 100644 --- a/term/serial.c +++ b/term/serial.c @@ -636,6 +636,21 @@ GRUB_MOD_INIT(serial) serial_settings.word_len = UART_8BITS_WORD; serial_settings.parity = UART_NO_PARITY; serial_settings.stop_bits = UART_1_STOP_BIT; + +#ifdef GRUB_MACHINE_MIPS_YEELOONG + { + grub_err_t hwiniterr; + hwiniterr = serial_hw_init (); + + if (hwiniterr == GRUB_ERR_NONE) + { + grub_term_register_input_active ("serial", &grub_serial_term_input); + grub_term_register_output_active ("serial", &grub_serial_term_output); + + registered = 1; + } + } +#endif } GRUB_MOD_FINI(serial) From 4b9fa9d70f80349aa97c76a5cedb402395787d8a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:08:52 +0200 Subject: [PATCH 236/503] Addmissing definitions --- include/grub/mips/loongson.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index 09b788db2..6cb1178d5 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -64,7 +64,7 @@ #define GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS 2 #define GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS 2 -/* Fixme: determine dynamically. */ +/* FIXME: determine dynamically. */ #define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19 #define GRUB_CPU_LOONGSON_COP0_BADVADDR GRUB_CPU_REGISTER_WRAP($8) @@ -81,6 +81,9 @@ #define GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE 0x100 #define GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU 0x200 +#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO 0xbfe00150 +#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI 0xbfe00154 + #define GRUB_CPU_LOONGSON_GPIOCFG 0xbfe00120 #define GRUB_CPU_LOONGSON_SHUTDOWN_GPIO 1 From 5667f2656d69cfeac04146a92d072b41710fceec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:09:39 +0200 Subject: [PATCH 237/503] Add missing part of serial commit --- include/grub/term.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/grub/term.h b/include/grub/term.h index 143aabe1e..9500e1c99 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -213,6 +213,14 @@ grub_term_register_input (const char *name __attribute__ ((unused)), } } +static inline void +grub_term_register_input_active (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + if (! term->init || term->init () == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); +} + static inline void grub_term_register_output (const char *name __attribute__ ((unused)), grub_term_output_t term) @@ -229,6 +237,15 @@ grub_term_register_output (const char *name __attribute__ ((unused)), } } +static inline void +grub_term_register_output_active (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + if (! term->init || term->init () == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); +} + static inline void grub_term_unregister_input (grub_term_input_t term) { From ae87524ea6e268013a315b230cd23716ef6dd705 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:11:47 +0200 Subject: [PATCH 238/503] Fix getvirt function on yeeloong --- bus/pci.c | 4 ++-- include/grub/pci.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bus/pci.c b/bus/pci.c index 2fe9d764e..3fec44fc2 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -36,7 +36,7 @@ grub_dma_free (struct grub_pci_dma_chunk *ch) #endif #ifdef GRUB_MACHINE_MIPS_YEELOONG -void * +volatile void * grub_dma_get_virt (struct grub_pci_dma_chunk *ch) { return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000); @@ -45,7 +45,7 @@ grub_dma_get_virt (struct grub_pci_dma_chunk *ch) grub_uint32_t grub_dma_get_phys (struct grub_pci_dma_chunk *ch) { - return ((grub_uint32_t) ch) & 0x1fffffff; + return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000; } #else diff --git a/include/grub/pci.h b/include/grub/pci.h index fff4d3e3a..51adf9377 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -115,7 +115,7 @@ struct grub_pci_dma_chunk; struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, grub_size_t size); void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); -void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); +volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); #endif From 980d936688f2308a8db23639201320ccb7d09493 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:12:33 +0200 Subject: [PATCH 239/503] Skip ghost USB controllers --- bus/pci.c | 8 ++++++++ include/grub/mips/yeeloong/pci.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/bus/pci.c b/bus/pci.c index 3fec44fc2..d8698ba33 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -91,6 +91,14 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) if (id >> 16 == 0xFFFF) continue; + /* Skip ghosts. */ + if (id == GRUB_YEELOONG_OHCI_PCIID + && dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION) + continue; + if (id == GRUB_YEELOONG_EHCI_PCIID + && dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION) + continue; + if (hook (dev, id)) return; diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index 7c816ac8e..199bac048 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -24,6 +24,11 @@ #include #endif +#define GRUB_YEELOONG_OHCI_PCIID 0x00351033 +#define GRUB_YEELOONG_EHCI_PCIID 0x00e01033 +#define GRUB_YEELOONG_OHCI_GHOST_FUNCTION 4 +#define GRUB_YEELOONG_EHCI_GHOST_FUNCTION 5 + #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 From 60c33f8c0fadde0cd6d266d612fa4050bd390db4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:13:37 +0200 Subject: [PATCH 240/503] Use DMA memory in usbtrans.c --- bus/usb/usbtrans.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index f59d5ec77..f6d3d30f9 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -35,12 +35,12 @@ grub_usb_control_msg (grub_usb_device_t dev, int i; grub_usb_transfer_t transfer; int datablocks; - struct grub_usb_packet_setup *setupdata; + volatile struct grub_usb_packet_setup *setupdata; grub_uint32_t setupdata_addr; grub_usb_err_t err; unsigned int max; struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk; - char *data; + volatile char *data; grub_uint32_t data_addr; grub_size_t size = size0; @@ -50,7 +50,7 @@ grub_usb_control_msg (grub_usb_device_t dev, return GRUB_USB_ERR_INTERNAL; data = grub_dma_get_virt (data_chunk); data_addr = grub_dma_get_phys (data_chunk); - grub_memcpy (data, data_in, size); + grub_memcpy ((char *) data, data_in, size); grub_dprintf ("usb", "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n", @@ -152,7 +152,7 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_dma_free (data_chunk); grub_dma_free (setupdata_chunk); - grub_memcpy (data_in, data, size0); + grub_memcpy (data_in, (char *) data, size0); return err; } @@ -168,7 +168,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, unsigned int max; grub_usb_err_t err; int toggle = dev->toggle[endpoint]; - char *data; + volatile char *data; grub_uint32_t data_addr; struct grub_pci_dma_chunk *data_chunk; grub_size_t size = size0; @@ -180,7 +180,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, data = grub_dma_get_virt (data_chunk); data_addr = grub_dma_get_phys (data_chunk); if (type == GRUB_USB_TRANSFER_TYPE_OUT) - grub_memcpy (data, data_in, size); + grub_memcpy ((char *) data, data_in, size); /* Use the maximum packet size given in the endpoint descriptor. */ if (dev->initialized) @@ -247,7 +247,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, grub_dma_free (data_chunk); if (type == GRUB_USB_TRANSFER_TYPE_IN) - grub_memcpy (data_in, data, size0); + grub_memcpy (data_in, (char *) data, size0); return err; } From 20ad3a81dc8c9d5c186ecf4361d1c70515008540 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:14:23 +0200 Subject: [PATCH 241/503] Macroify USB controllers ID --- kern/mips/yeeloong/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 78586dbd4..46b3af2e1 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -78,13 +78,13 @@ init_pci (void) /* FIXME: autoscan for BARs and devices. */ switch (pciid) { - case 0x00351033: + case GRUB_YEELOONG_OHCI_PCIID: addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5025000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); grub_pci_write (addr, 0x2100146); break; - case 0x00e01033: + case GRUB_YEELOONG_EHCI_PCIID: addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5026000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); From c710f8cc096a84178931e6a9b867e10f0ae75fa3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:17:16 +0200 Subject: [PATCH 242/503] Always write the whole of frame interval register --- bus/usb/ohci.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 81ce3294d..b86e78ef2 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -104,10 +104,12 @@ typedef enum #define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 #define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT 0 /* XXX: Is this choice of timings sane? */ #define GRUB_OHCI_FSMPS 0x2778 #define GRUB_OHCI_PERIODIC_START 0x257f +#define GRUB_OHCI_FRAME_INTERVAL 0x2edf static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) @@ -135,11 +137,11 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_address_t addr; struct grub_ohci *o; grub_uint32_t revision; - grub_uint32_t frame_interval; int cs5536; /* Determine IO base address. */ grub_dprintf ("ohci", "pciid = %x\n", pciid); + if (pciid == GRUB_CS5536_PCIID) { grub_uint64_t basereg; @@ -215,19 +217,16 @@ grub_ohci_pci_iter (grub_pci_device_t dev, & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) | GRUB_OHCI_RHUB_PORT_ALL_POWERED); - /* 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. */ - frame_interval = (frame_interval & ~GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK) - | (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT - << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, + (GRUB_OHCI_FSMPS + << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT) + | (GRUB_OHCI_FRAME_INTERVAL + << GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT)); grub_ohci_writereg32 (o, GRUB_OHCI_REG_PERIODIC_START, GRUB_OHCI_PERIODIC_START); From e51a665432fafb4016613be732f45f24ffa4eb23 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 00:17:51 +0200 Subject: [PATCH 243/503] Add missing volatile attribute --- bus/usb/ohci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index b86e78ef2..9515423fa 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -64,8 +64,8 @@ struct grub_ohci_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; +typedef volatile struct grub_ohci_td *grub_ohci_td_t; +typedef volatile struct grub_ohci_ed *grub_ohci_ed_t; struct grub_ohci { From 27cd973df6fc3cc528a43f1f4d078ab296c5ef5f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 02:41:16 +0200 Subject: [PATCH 244/503] Macroify command and status registers --- include/grub/pci.h | 13 +++++++++++++ kern/mips/yeeloong/init.c | 29 +++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/include/grub/pci.h b/include/grub/pci.h index 51adf9377..e6d6488f0 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -68,6 +68,19 @@ #define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MAX_LAT 0x3f +#define GRUB_PCI_COMMAND_IO_ENABLED 0x0001 +#define GRUB_PCI_COMMAND_MEM_ENABLED 0x0002 +#define GRUB_PCI_COMMAND_BUS_MASTER 0x0004 +#define GRUB_PCI_COMMAND_PARITY_ERROR 0x0040 +#define GRUB_PCI_COMMAND_SERR_ENABLE 0x0100 + +#define GRUB_PCI_STATUS_CAPABILITIES 0x0010 +#define GRUB_PCI_STATUS_66MHZ_CAPABLE 0x0020 +#define GRUB_PCI_STATUS_FAST_B2B_CAPABLE 0x0080 + +#define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9 +#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 + #ifndef ASM_FILE typedef grub_uint32_t grub_pci_id_t; diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 46b3af2e1..523f90282 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -82,13 +82,26 @@ init_pci (void) addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5025000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, 0x2100146); + grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE + | GRUB_PCI_COMMAND_PARITY_ERROR + | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); + grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); break; case GRUB_YEELOONG_EHCI_PCIID: addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5026000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, 0x2100146); + grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE + | GRUB_PCI_COMMAND_PARITY_ERROR + | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); + grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) + | GRUB_PCI_STATUS_CAPABILITIES); break; } return 0; @@ -98,8 +111,16 @@ init_pci (void) *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff; /* Setup PCI controller. */ - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_COMMAND)) = 0x22b00046; + *((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_COMMAND)) + = GRUB_PCI_COMMAND_PARITY_ERROR | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED; + *((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_STATUS)) + = (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) + | GRUB_PCI_STATUS_FAST_B2B_CAPABLE | GRUB_PCI_STATUS_66MHZ_CAPABLE + | GRUB_PCI_STATUS_CAPABILITIES; + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + GRUB_PCI_REG_CACHELINE)) = 0xff; *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER From 5f2316c1fe5ad62c3ae5815c256313041e6a559d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:42:16 +0200 Subject: [PATCH 245/503] * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. * term/gfxterm.c (real_scroll): Likewise. --- ChangeLog | 5 +++++ gfxmenu/gfxmenu.c | 7 +++++++ term/gfxterm.c | 22 +++++++++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02d16e835..cdeee7c2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. + * term/gfxterm.c (real_scroll): Likewise. + 2010-05-21 Vladimir Serbinenko * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index a2e765156..1acab9ca7 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -110,6 +110,13 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) view->nested = nested; view->first_timeout = -1; + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + if (view->double_repaint) + { + grub_video_swap_buffers (); + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + } + grub_gfxmenu_view_draw (view); instance->data = view; diff --git a/term/gfxterm.c b/term/gfxterm.c index ecfe4ff3b..c57d0f0fa 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -707,12 +707,6 @@ real_scroll (void) draw_cursor (0); grub_video_set_active_render_target (render_target); - /* Save viewport and set it to our window. */ - grub_video_get_viewport ((unsigned *) &saved_view.x, - (unsigned *) &saved_view.y, - (unsigned *) &saved_view.width, - (unsigned *) &saved_view.height); - grub_video_set_viewport (window.x, window.y, window.width, window.height); i = window.double_repaint ? 2 : 1; @@ -720,6 +714,15 @@ real_scroll (void) while (i--) { + /* Save viewport and set it to our window. */ + grub_video_get_viewport ((unsigned *) &saved_view.x, + (unsigned *) &saved_view.y, + (unsigned *) &saved_view.width, + (unsigned *) &saved_view.height); + + grub_video_set_viewport (window.x, window.y, window.width, + window.height); + /* Clear new border area. */ grub_video_fill_rect (color, virtual_screen.offset_x, @@ -735,6 +738,10 @@ real_scroll (void) grub_video_scroll (color, 0, -virtual_screen.normal_char_height * virtual_screen.total_scroll); + /* Restore saved viewport. */ + grub_video_set_viewport (saved_view.x, saved_view.y, + saved_view.width, saved_view.height); + if (i) grub_video_swap_buffers (); } @@ -746,9 +753,6 @@ real_scroll (void) grub_video_scroll (color, 0, -virtual_screen.normal_char_height * virtual_screen.total_scroll); - /* Restore saved viewport. */ - grub_video_set_viewport (saved_view.x, saved_view.y, - saved_view.width, saved_view.height); grub_video_set_active_render_target (render_target); } From 3ecb080a33a3cb3e15ca7721c00eeb96d9e8ed3e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:43:38 +0200 Subject: [PATCH 246/503] * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current buffer since gfxterm handles double repaint. --- ChangeLog | 5 +++++ gfxmenu/view.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdeee7c2b..dbf6f23eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current + buffer since gfxterm handles double repaint. + 2010-05-23 Vladimir Serbinenko * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 9a5671cdd..518c3ba53 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -357,11 +357,6 @@ grub_gfxmenu_draw_terminal_box (void) term_box->draw (term_box, term_rect.x - term_box->get_left_pad (term_box), term_rect.y - term_box->get_top_pad (term_box)); - grub_video_swap_buffers (); - if (term_view->double_repaint) - term_box->draw (term_box, - term_rect.x - term_box->get_left_pad (term_box), - term_rect.y - term_box->get_top_pad (term_box)); } static void From ad603f61a5f61677406aad7b7c041ef21de8957f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:59:50 +0200 Subject: [PATCH 247/503] * gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding. Removed drawing_scrollbar argument. All users updated Fixes #29792. Reported by Jo Shields --- ChangeLog | 7 +++++++ gfxmenu/gui_list.c | 15 ++++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbf6f23eb..65bd6ad03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding. + Removed drawing_scrollbar argument. All users updated + Fixes #29792. + Reported by Jo Shields + 2010-05-23 Vladimir Serbinenko * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index 0d771413f..8583a214e 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -210,8 +210,7 @@ draw_scrollbar (list_impl_t self, /* Draw the list of items. */ static void -draw_menu (list_impl_t self, int width, int drawing_scrollbar, - int num_shown_items) +draw_menu (list_impl_t self, int width, int num_shown_items) { if (! self->menu_box || ! self->selected_item_box) return; @@ -226,8 +225,6 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar, make_selected_item_visible (self); - int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0; - grub_gfxmenu_box_t selbox = self->selected_item_box; int sel_leftpad = selbox->get_left_pad (selbox); int item_top = boxpad; @@ -244,12 +241,8 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar, if (is_selected) { int sel_toppad = selbox->get_top_pad (selbox); - selbox->set_content_size (selbox, - (width - 2 * boxpad - - scrollbar_h_space), - item_height); - selbox->draw (selbox, - item_left - sel_leftpad, + selbox->set_content_size (selbox, (width - 2 * boxpad), item_height); + selbox->draw (selbox, item_left - sel_leftpad, item_top - sel_toppad); } @@ -320,7 +313,7 @@ list_paint (void *vself, const grub_video_rect_t *region) box->draw (box, 0, 0); grub_gui_set_viewport (&content_rect, &vpsave2); - draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items); + draw_menu (self, content_rect.width, num_shown_items); grub_gui_restore_viewport (&vpsave2); if (drawing_scrollbar) From 76e6d0d767b295f2249b8320a719fe0cd8ea66ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 14:11:11 +0200 Subject: [PATCH 248/503] Add default/grub support --- docs/grub.texi | 16 +++++++++++ util/grub-mkconfig.in | 4 +++ util/grub.d/00_header.in | 57 +++++++++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index 704f8b2a3..938fedbaf 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -80,6 +80,7 @@ This edition documents version @value{VERSION}. * Configuration:: Writing your own configuration file * Network:: Downloading OS images from a network * Serial terminal:: Using GRUB via a serial line +* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys * Preset Menu:: Embedding a configuration file into GRUB * Images:: GRUB image files * Filesystem:: Filesystem syntax and semantics @@ -747,6 +748,21 @@ 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 Vendor power-on keys +@chapter Using GRUB with vendor power-on keys +Some laptop vendor provide an additional power-on button which boots another OS. +GRUB supports such buttons with GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON, +GRUB_HIDDEN_TIMEOUT_BUTTON and GRUB_BUTTON_CMOS_ADDRESS variables in +default/grub. GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON and +GRUB_HIDDEN_TIMEOUT_BUTTON are used instead of corresponding variables without +_BUTTON suffix when powered using special button. +GRUB_BUTTON_CMOS_ADDRESS is vendor specific and partially model-specific. +Values known to GRUB team are: + +@table @key +@item Dell XPS M1530 +85:3 +@end table @node Filesystem @chapter Filesystem syntax and semantics diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index d1abfa36a..0095e1ce8 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -246,6 +246,10 @@ export GRUB_DEFAULT \ GRUB_HIDDEN_TIMEOUT \ GRUB_HIDDEN_TIMEOUT_QUIET \ GRUB_TIMEOUT \ + GRUB_DEFAULT_BUTTON \ + GRUB_HIDDEN_TIMEOUT_BUTTON \ + GRUB_TIMEOUT_BUTTON \ + GRUB_BUTTON_CMOS_ADDRESS \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index d181fdffc..df8f5dfaa 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -38,11 +38,29 @@ if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi +if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi +if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi +if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi + cat << EOF if [ -s \$prefix/grubenv ]; then load_env fi +EOF +if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then + cat < Date: Sun, 23 May 2010 14:37:28 +0200 Subject: [PATCH 249/503] * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. --- ChangeLog | 4 ++++ commands/usbtest.c | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39a658288..01d2dbf7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-23 Vladimir Serbinenko + + * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. + 2010-05-23 Vladimir Serbinenko cmostest support. diff --git a/commands/usbtest.c b/commands/usbtest.c index b884a93f1..191c4e4df 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -83,15 +83,24 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, 0x06, (3 << 8) | index, langid, descstr.length, (char *) descstrp); - *string = grub_malloc (descstr.length / 2); + if (descstrp->length == 0) + { + grub_free (descstrp); + *string = grub_strdup (""); + if (! *string) + return GRUB_USB_ERR_INTERNAL; + return GRUB_USB_ERR_NONE; + } + + *string = grub_malloc (descstr.length * 2 + 1); 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_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, + descstrp->length / 2 - 1) = 0; grub_free (descstrp); return GRUB_USB_ERR_NONE; From 7eaef0ed512fb3547b318c571681c7a649865387 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 May 2010 20:43:43 +0200 Subject: [PATCH 250/503] fix compilation on not-yeeloong --- bus/pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bus/pci.c b/bus/pci.c index d8698ba33..3e2126962 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -49,7 +49,7 @@ grub_dma_get_phys (struct grub_pci_dma_chunk *ch) } #else -void * +volatile void * grub_dma_get_virt (struct grub_pci_dma_chunk *ch) { return (void *) ch; @@ -91,6 +91,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) if (id >> 16 == 0xFFFF) continue; +#ifdef GRUB_MACHINE_MIPS_YEELOONG /* Skip ghosts. */ if (id == GRUB_YEELOONG_OHCI_PCIID && dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION) @@ -98,6 +99,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) if (id == GRUB_YEELOONG_EHCI_PCIID && dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION) continue; +#endif if (hook (dev, id)) return; From 7d8c0213538e9954d3b466d91c6c7c3c0f10b300 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 25 May 2010 18:24:46 +0530 Subject: [PATCH 251/503] * INSTALL: Added flex >= 2.5.35 requirement. --- ChangeLog | 4 ++++ INSTALL | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 01d2dbf7c..b8e66c7a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-25 BVK Chaitanya + + * INSTALL: Added flex >= 2.5.35 requirement. + 2010-05-23 Vladimir Serbinenko * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. diff --git a/INSTALL b/INSTALL index 0dd408bcc..7186d20db 100644 --- a/INSTALL +++ b/INSTALL @@ -16,6 +16,7 @@ configuring the GRUB. * GNU Bison 2.3 or later * GNU gettext 0.17 or later * GNU binutils 2.9.1.0.23 or later +* Flex 2.5.35 or later * Other standard GNU/Unix tools If you use a development snapshot or want to hack on GRUB you may From 95ac3c730c58a60ec8a64bf046d235eec95eb790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Wed, 26 May 2010 23:49:52 +0200 Subject: [PATCH 252/503] Fix -Wshadow warning with emu build on NetBSD. --- ChangeLog | 5 +++++ kern/emu/hostdisk.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8e66c7a2..ff7d02b44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-26 Grégoire Sutre + + * kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed + variable index into p_index to suppress a warning with -Wshadow. + 2010-05-25 BVK Chaitanya * INSTALL: Added flex >= 2.5.35 requirement. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 9c4697552..ae2f7d9ad 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -338,7 +338,7 @@ find_partition_start (const char *dev) struct hd_geometry hdg; # else /* defined(__NetBSD__) */ struct disklabel label; - int index; + int p_index; # endif /* !defined(__NetBSD__) */ # ifdef HAVE_DEVICE_MAPPER @@ -435,15 +435,15 @@ devmapper_fail: # if !defined(__NetBSD__) return hdg.start; # else /* defined(__NetBSD__) */ - index = dev[strlen(dev) - 1] - 'a'; + p_index = dev[strlen(dev) - 1] - 'a'; - if (index >= label.d_npartitions) + if (p_index >= label.d_npartitions) { grub_error (GRUB_ERR_BAD_DEVICE, "no disk label entry for `%s'", dev); return 0; } - return (grub_disk_addr_t) label.d_partitions[index].p_offset; + return (grub_disk_addr_t) label.d_partitions[p_index].p_offset; # endif /* !defined(__NetBSD__) */ } #endif /* __linux__ || __CYGWIN__ */ From d1d368e426d3a0554ec28f52dafbd644fd21816e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 12:43:22 +0100 Subject: [PATCH 253/503] * util/grub-mkrescue.in: Initialise override_dir rather than assuming that it's unset or empty in the environment. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index ff7d02b44..22005fbb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-27 Colin Watson + + * util/grub-mkrescue.in: Initialise override_dir rather than + assuming that it's unset or empty in the environment. + 2010-05-26 Grégoire Sutre * kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 7e7253006..99b10de7b 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -37,6 +37,7 @@ pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi rom_directory= +override_dir= grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage From 5fdba519bb35c64a2c90221f069863cc36e00387 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 27 May 2010 16:38:16 +0200 Subject: [PATCH 254/503] 2010-05-27 Robert Millan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert partmap module to handle cross-partmap setups. Reported by Orestes Mas. Gràcies! --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 22005fbb9..18c2abeac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-27 Robert Millan + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert + partmap module to handle cross-partmap setups. + Reported by Orestes Mas. Gràcies! + 2010-05-27 Colin Watson * util/grub-mkrescue.in: Initialise override_dir rather than diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index f4674b257..7ec8cb5be 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -105,6 +105,11 @@ prepare_grub_to_access_device () echo "insmod ${module}" done + partmap="`${grub_probe} --device ${device} --target=partmap`" + for module in ${partmap} ; do + echo "insmod ${module}" + done + fs="`${grub_probe} --device ${device} --target=fs`" for module in ${fs} ; do echo "insmod ${module}" From db2102a0468e15c76bb369eef728622a9e51683e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 15:45:41 +0100 Subject: [PATCH 255/503] * kern/emu/misc.c (canonicalize_file_name): realpath can still return NULL for various reasons even if it has a maximum-length buffer: for example, there might be a symlink loop, or the path might exceed PATH_MAX. If this happens, return NULL. --- ChangeLog | 7 +++++++ kern/emu/misc.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 18c2abeac..34bc31bf9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-27 Colin Watson + + * kern/emu/misc.c (canonicalize_file_name): realpath can still + return NULL for various reasons even if it has a maximum-length + buffer: for example, there might be a symlink loop, or the path + might exceed PATH_MAX. If this happens, return NULL. + 2010-05-27 Robert Millan * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert diff --git a/kern/emu/misc.c b/kern/emu/misc.c index a3ccb3076..9437169e0 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -185,7 +185,8 @@ canonicalize_file_name (const char *path) char *ret; #ifdef PATH_MAX ret = xmalloc (PATH_MAX); - (void) realpath (path, ret); + if (!realpath (path, ret)) + return NULL; #else ret = realpath (path, NULL); #endif From d870813427f6e58ddc6877a578ae5b882f6f0898 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 15:54:18 +0100 Subject: [PATCH 256/503] * util/grub-script-check.c (main): Ensure defined behaviour on empty input files (in which case exit zero). --- ChangeLog | 5 +++++ util/grub-script-check.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34bc31bf9..a8e3e5284 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-27 Colin Watson + + * util/grub-script-check.c (main): Ensure defined behaviour on empty + input files (in which case exit zero). + 2010-05-27 Colin Watson * kern/emu/misc.c (canonicalize_file_name): realpath can still diff --git a/util/grub-script-check.c b/util/grub-script-check.c index dc732aa01..e69f787f5 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -145,7 +145,8 @@ main (int argc, char *argv[]) char *input; FILE *file = 0; int verbose = 0; - struct grub_script *script; + int found_input = 0; + struct grub_script *script = NULL; auto grub_err_t get_config_line (char **line, int cont); grub_err_t get_config_line (char **line, int cont __attribute__ ((unused))) @@ -247,6 +248,7 @@ main (int argc, char *argv[]) get_config_line(&input, 0); if (! input) break; + found_input = 1; script = grub_script_parse (input, get_config_line); if (script) @@ -262,5 +264,5 @@ main (int argc, char *argv[]) grub_fini_all (); if (file) fclose (file); - return (script == 0); + return (found_input && script == 0); } From 15fb2ae896e6aad4ba947a5b4828f938575c9877 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 28 May 2010 11:51:50 +0100 Subject: [PATCH 257/503] Make grub-probe work with symbolic links under /dev/mapper as well as with real block devices. The Linux world seems to be (at best) in transition here, and GRUB shouldn't get caught in the middle. * kern/emu/getroot.c (find_root_device): Follow symbolic links under /dev/mapper. --- ChangeLog.mapper-symlink | 8 ++++++++ kern/emu/getroot.c | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 ChangeLog.mapper-symlink diff --git a/ChangeLog.mapper-symlink b/ChangeLog.mapper-symlink new file mode 100644 index 000000000..afcfc6479 --- /dev/null +++ b/ChangeLog.mapper-symlink @@ -0,0 +1,8 @@ +2010-05-28 Colin Watson + + Make grub-probe work with symbolic links under /dev/mapper as well + as with real block devices. The Linux world seems to be (at best) + in transition here, and GRUB shouldn't get caught in the middle. + + * kern/emu/getroot.c (find_root_device): Follow symbolic links under + /dev/mapper. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6875044da..e62abe089 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -126,9 +126,20 @@ find_root_device (const char *dir, dev_t dev) /* Ignore any error. */ continue; - if (S_ISLNK (st.st_mode)) - /* Don't follow symbolic links. */ + if (S_ISLNK (st.st_mode)) { +#ifdef __linux__ + if (strcmp (dir, "mapper") == 0) { + /* Follow symbolic links under /dev/mapper/; the canonical name + may be something like /dev/dm-0, but the names under + /dev/mapper/ are more human-readable and so we prefer them if + we can get them. */ + if (stat (ent->d_name, &st) < 0) + continue; + } else +#endif /* __linux__ */ + /* Don't follow other symbolic links. */ continue; + } if (S_ISDIR (st.st_mode)) { From fa4b84900afa71ad9fcf498d509e8f0e8abbb6dc Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 28 May 2010 19:18:45 +0530 Subject: [PATCH 258/503] Fix grub-emu issues on NetBSD, with gcc 4.1.3. * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. * kern/misc.c (__enable_execute_stack): Disable on GRUB_MACHINE_EMU. --- ChangeLog | 9 +++++++++ conf/any-emu.rmk | 2 -- include/grub/emu/misc.h | 1 + kern/misc.c | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 965848669..e3fb344aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-05-28 BVK Chaitanya + + Fix grub-emu issues on NetBSD, with gcc 4.1.3. + + * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. + * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. + * kern/misc.c (__enable_execute_stack): Disable on + GRUB_MACHINE_EMU. + 2010-05-28 Colin Watson Make grub-probe work with symbolic links under /dev/mapper as well diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 3f0df06aa..000996172 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) - kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index e037e6be7..0e6ace0e8 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -46,5 +46,6 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); #endif char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); +extern char * canonicalize_file_name (const char *path); #endif /* GRUB_EMU_MISC_H */ diff --git a/kern/misc.c b/kern/misc.c index ccc01d43f..2ba34f235 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1058,7 +1058,7 @@ grub_abort (void) void abort (void) __attribute__ ((alias ("grub_abort"))); #endif -#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) +#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU) /* Some gcc versions generate a call to this function in trampolines for nested functions. */ void __enable_execute_stack (void *addr __attribute__ ((unused))) @@ -1075,3 +1075,4 @@ void __deregister_frame_info (void) { } #endif + From c7c75cf4cb568889432527f94efc0d971e2cc3b0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 28 May 2010 18:13:48 +0100 Subject: [PATCH 259/503] * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not to the empty string. --- ChangeLog | 5 +++++ configure.ac | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e3fb344aa..5072a6026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-28 Colin Watson + + * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not + to the empty string. + 2010-05-28 BVK Chaitanya Fix grub-emu issues on NetBSD, with gcc 4.1.3. diff --git a/configure.ac b/configure.ac index ace6bd81d..31b179d46 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ AC_PROG_LEX AC_PROG_MAKE_SET AC_PROG_MKDIR_P -if test "x$LEX" = x; then +if test "x$LEX" = "x:"; then AC_MSG_ERROR([flex is not found]) else version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` From 8148171e96f291ad36b1d58e2332d41552f73992 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 08:24:33 +0200 Subject: [PATCH 260/503] Pad image to 512K for flashrom --- util/grub-mkimage.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index bb4a9b2eb..dc9dcc208 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1015,14 +1015,17 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], boot_size = grub_util_get_image_size (boot_path); boot_img = grub_util_read_image (boot_path); - rom_size = core_size + boot_size; + rom_size = ALIGN_UP (core_size + boot_size, 512 * 1024); rom_img = xmalloc (rom_size); memset (rom_img, 0, rom_size); memcpy (rom_img, boot_img, boot_size); - memcpy (rom_img + boot_size, core_img, core_size); + memcpy (rom_img + boot_size, core_img, core_size); + + memset (rom_img + boot_size + core_size, 0, + rom_size - (boot_size + core_size)); free (core_img); core_img = rom_img; From 4fa54f9209d3c71f7e33dd37df0a0c87892524eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 08:25:20 +0200 Subject: [PATCH 261/503] Remove leftover message --- boot/mips/yeeloong/fwstart.S | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/mips/yeeloong/fwstart.S b/boot/mips/yeeloong/fwstart.S index 239305939..7fe5d7ac2 100644 --- a/boot/mips/yeeloong/fwstart.S +++ b/boot/mips/yeeloong/fwstart.S @@ -381,7 +381,6 @@ notification_string: .asciz "GRUB " no_cs5536: .asciz "No CS5536 found.\n\r" cs5536_found: .asciz "CS5536 at " sm_failed: .asciz "SM transaction failed.\n\r" -not_implemented: .asciz "Nothing more is implemented. Bye.\n\r" unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r" unhandled_cache_error: .asciz "Unhandled cache error.\n\r" unhandled_exception: .asciz "Unhandled exception.\n\r" From 8b1cf5e87f603a30dbc0e0d13c44c3628d67b2bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 13:58:18 +0200 Subject: [PATCH 262/503] Dedicated DMA allocation functions. CS5536 OHCI support. --- bus/cs5536.c | 215 +++++++++++++++++++++++++++++++ bus/pci.c | 53 ++++++++ bus/usb/ohci.c | 175 +++++++++++++++++-------- bus/usb/uhci.c | 6 +- bus/usb/usbtrans.c | 91 ++++++++++--- conf/i386.rmk | 6 + conf/mips-yeeloong.rmk | 34 ++++- include/grub/cs5536.h | 190 +++++++++++++++++++++++++++ include/grub/i386/pci.h | 2 +- include/grub/mips/yeeloong/pci.h | 32 +++-- include/grub/pci.h | 26 ++++ include/grub/smbus.h | 70 ++++++++++ include/grub/usbtrans.h | 2 +- 13 files changed, 817 insertions(+), 85 deletions(-) create mode 100644 bus/cs5536.c create mode 100644 include/grub/cs5536.h create mode 100644 include/grub/smbus.h diff --git a/bus/cs5536.c b/bus/cs5536.c new file mode 100644 index 000000000..61b0646b4 --- /dev/null +++ b/bus/cs5536.c @@ -0,0 +1,215 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +int +grub_cs5536_find (grub_pci_device_t *devp) +{ + int found = 0; + auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid); + + int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid) + { + if (pciid == GRUB_CS5536_PCIID) + { + *devp = dev; + found = 1; + return 1; + } + return 0; + } + + grub_pci_iterate (hook); + + return found; +} + +grub_uint64_t +grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr) +{ + grub_uint64_t ret = 0; + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + ret = (grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0)); + ret |= (((grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, + GRUB_CS5536_MSR_MAILBOX_DATA1))) + << 32); + return ret; +} + +void +grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr, + grub_uint64_t val) +{ + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0), + val & 0xffffffff); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1), + val >> 32); +} + +grub_err_t +grub_cs5536_smbus_wait (grub_port_t smbbase) +{ + grub_uint64_t start = grub_get_time_ms (); + while (1) + { + grub_uint8_t status; + status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS); + if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST) + return GRUB_ERR_NONE; + if (status & GRUB_CS5536_SMB_REG_STATUS_BER) + return grub_error (GRUB_ERR_IO, "SM bus error"); + if (status & GRUB_CS5536_SMB_REG_STATUS_NACK) + return grub_error (GRUB_ERR_IO, "NACK received"); + if (grub_get_time_ms () > start + 40) + return grub_error (GRUB_ERR_IO, "SM stalled"); + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res) +{ + grub_err_t err; + + /* Send START. */ + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send ACK. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_ACK, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send byte address. */ + grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send START. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb ((dev << 1) | 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send STOP. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_STOP, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + *res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, + grub_port_t *smbbase) +{ + grub_uint64_t smbbar; + + smbbar = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_SMB_BAR); + + /* FIXME */ + if (!(smbbar & GRUB_CS5536_LBAR_ENABLE)) + return grub_error(GRUB_ERR_IO, "SMB controller not enabled\n"); + *smbbase = (smbbar & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE; + + if (divisor < 8) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid divisor"); + + /* Disable SMB. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + /* Disable interrupts. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Set as master. */ + grub_outb (GRUB_CS5536_SMB_REG_ADDR_MASTER, + *smbbase + GRUB_CS5536_SMB_REG_ADDR); + + /* Launch. */ + grub_outb (((divisor >> 7) & 0xff), *smbbase + GRUB_CS5536_SMB_REG_CTRL3); + grub_outb (((divisor << 1) & 0xfe) | GRUB_CS5536_SMB_REG_CTRL2_ENABLE, + *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, + struct grub_smbus_spd *res) +{ + grub_err_t err; + grub_size_t size; + grub_uint8_t b; + grub_size_t ptr; + + err = grub_cs5536_read_spd_byte (smbbase, dev, 0, &b); + if (err) + return err; + if (b == 0) + return grub_error (GRUB_ERR_IO, "no SPD found"); + size = b; + + ((grub_uint8_t *) res)[0] = b; + for (ptr = 1; ptr < size; ptr++) + { + err = grub_cs5536_read_spd_byte (smbbase, dev, ptr, + &((grub_uint8_t *) res)[ptr]); + if (err) + return err; + } + return GRUB_ERR_NONE; +} + diff --git a/bus/pci.c b/bus/pci.c index a08e53446..3e2126962 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -19,6 +19,49 @@ #include #include +#include + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 +struct grub_pci_dma_chunk * +grub_memalign_dma32 (grub_size_t align, grub_size_t size) +{ + return grub_memalign (align, size); +} + +void +grub_dma_free (struct grub_pci_dma_chunk *ch) +{ + grub_free (ch); +} +#endif + +#ifdef GRUB_MACHINE_MIPS_YEELOONG +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000); +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000; +} +#else + +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ch; +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (grub_uint32_t) ch; +} + +#endif grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) @@ -48,6 +91,16 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) if (id >> 16 == 0xFFFF) continue; +#ifdef GRUB_MACHINE_MIPS_YEELOONG + /* Skip ghosts. */ + if (id == GRUB_YEELOONG_OHCI_PCIID + && dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION) + continue; + if (id == GRUB_YEELOONG_EHCI_PCIID + && dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION) + continue; +#endif + if (hook (dev, id)) return; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 6d185bc7f..7294fe537 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -24,8 +24,9 @@ #include #include #include -#include +#include #include +#include struct grub_ohci_hcca { @@ -63,13 +64,15 @@ struct grub_ohci_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; +typedef volatile struct grub_ohci_td *grub_ohci_td_t; +typedef volatile struct grub_ohci_ed *grub_ohci_ed_t; struct grub_ohci { volatile grub_uint32_t *iobase; volatile struct grub_ohci_hcca *hcca; + grub_uint32_t hcca_addr; + struct grub_pci_dma_chunk *hcca_chunk; struct grub_ohci *next; }; @@ -91,10 +94,23 @@ typedef enum GRUB_OHCI_REG_BULKCURR, GRUB_OHCI_REG_DONEHEAD, GRUB_OHCI_REG_FRAME_INTERVAL, + GRUB_OHCI_REG_PERIODIC_START = 16, GRUB_OHCI_REG_RHUBA = 18, GRUB_OHCI_REG_RHUBPORT = 21 } grub_ohci_reg_t; +#define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 +#define GRUB_OHCI_RHUB_PORT_ALL_POWERED 0x200 + +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT 0 + +/* XXX: Is this choice of timings sane? */ +#define GRUB_OHCI_FSMPS 0x2778 +#define GRUB_OHCI_PERIODIC_START 0x257f +#define GRUB_OHCI_FRAME_INTERVAL 0x2edf + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -114,51 +130,81 @@ grub_ohci_writereg32 (struct grub_ohci *o, controller. If this is the case, initialize it. */ static int NESTED_FUNC_ATTR grub_ohci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused))) + grub_pci_id_t pciid) { - grub_uint32_t class_code; - grub_uint32_t class; - grub_uint32_t subclass; grub_uint32_t 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 (dev, GRUB_PCI_REG_CLASS); - class_code = grub_pci_read (addr) >> 8; - - interf = class_code & 0xFF; - subclass = (class_code >> 8) & 0xFF; - class = class_code >> 16; - - /* If this is not an OHCI controller, just return. */ - if (class != 0x0c || subclass != 0x03 || interf != 0x10) - return 0; + int cs5536; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); + grub_dprintf ("ohci", "pciid = %x\n", pciid); + + if (pciid == GRUB_CS5536_PCIID) + { + grub_uint64_t basereg; + + cs5536 = 1; + basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE); + if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) + { + /* Shouldn't happen. */ + grub_dprintf ("ohci", "No OHCI address is assigned\n"); + return 0; + } + base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); + basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg); + } + else + { + grub_uint32_t class_code; + grub_uint32_t class; + grub_uint32_t subclass; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class_code = grub_pci_read (addr) >> 8; + + interf = class_code & 0xFF; + subclass = (class_code >> 8) & 0xFF; + class = class_code >> 16; + + /* If this is not an OHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03 || interf != 0x10) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + base = grub_pci_read (addr); #if 0 - /* Stop if there is no IO space base address defined. */ - if (! (base & 1)) - return 0; + /* Stop if there is no IO space base address defined. */ + if (! (base & 1)) + return 0; #endif + grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n", + class, subclass, interf); + } + /* Allocate memory for the controller and register it. */ o = grub_malloc (sizeof (*o)); if (! o) return 1; - o->iobase = (grub_uint32_t *) base; + o->iobase = grub_pci_device_map_range (dev, base, 0x100); + + grub_dprintf ("ohci", "base=%p\n", o->iobase); /* Reserve memory for the HCCA. */ - o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); - - grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n", - class, subclass, interf, o->iobase); + o->hcca_chunk = grub_memalign_dma32 (256, 256); + if (! o->hcca_chunk) + return 1; + o->hcca = grub_dma_get_virt (o->hcca_chunk); + o->hcca_addr = grub_dma_get_phys (o->hcca_chunk); /* Check if the OHCI revision is actually 1.0 as supported. */ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); @@ -166,19 +212,27 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - /* Backup the frame interval register. */ - frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) + & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) + | GRUB_OHCI_RHUB_PORT_ALL_POWERED); /* 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); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, + (GRUB_OHCI_FSMPS + << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT) + | (GRUB_OHCI_FRAME_INTERVAL + << GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT)); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_PERIODIC_START, + GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -194,11 +248,13 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: +#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) grub_free ((void *) o->hcca); +#endif grub_free (o); - return 1; + return 0; } @@ -229,7 +285,7 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) 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_size_t size, grub_uint32_t data) { grub_uint32_t token; grub_uint32_t buffer; @@ -261,7 +317,7 @@ grub_ohci_transaction (grub_ohci_td_t td, token |= toggle << 24; token |= 1 << 25; - buffer = (grub_uint32_t) data; + buffer = data; buffer_end = buffer + size - 1; td->token = grub_cpu_to_le32 (token); @@ -276,7 +332,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, { struct grub_ohci *o = (struct grub_ohci *) dev->data; grub_ohci_ed_t ed; + grub_uint32_t ed_addr; + struct grub_pci_dma_chunk *ed_chunk, *td_list_chunk; grub_ohci_td_t td_list; + grub_uint32_t td_list_addr; grub_uint32_t target; grub_uint32_t td_tail; grub_uint32_t td_head; @@ -286,18 +345,23 @@ grub_ohci_transfer (grub_usb_controller_t dev, int i; /* Allocate an Endpoint Descriptor. */ - ed = grub_memalign (16, sizeof (*ed)); - if (! ed) + ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); + if (! ed_chunk) return GRUB_USB_ERR_INTERNAL; + ed = grub_dma_get_virt (ed_chunk); + ed_addr = grub_dma_get_phys (ed_chunk); - td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1)); - if (! td_list) + td_list_chunk = grub_memalign_dma32 (256, sizeof (*td_list) + * (transfer->transcnt + 1)); + if (! td_list_chunk) { - grub_free ((void *) ed); + grub_dma_free (ed_chunk); return GRUB_USB_ERR_INTERNAL; } + td_list = grub_dma_get_virt (td_list_chunk); + td_list_addr = grub_dma_get_phys (td_list_chunk); - grub_dprintf ("ohci", "alloc=%p\n", td_list); + grub_dprintf ("ohci", "alloc=%p/0x%x\n", td_list, td_list_addr); /* Setup all Transfer Descriptors. */ for (i = 0; i < transfer->transcnt; i++) @@ -307,7 +371,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, 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]); + td_list[i].next_td = grub_cpu_to_le32 (td_list_addr + + (i + 1) * sizeof (td_list[0])); } /* Setup the Endpoint Descriptor. */ @@ -324,9 +389,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Set the maximum packet size. */ target |= transfer->max << 16; - td_head = (grub_uint32_t) td_list; + td_head = td_list_addr; - td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; + td_tail = td_list_addr + transfer->transcnt * sizeof (*td_list); ed->target = grub_cpu_to_le32 (target); ed->td_head = grub_cpu_to_le32 (td_head); @@ -353,7 +418,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 2); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); /* Enable the Bulk list. */ control |= 1 << 5; @@ -380,10 +445,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, 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, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - (grub_uint32_t) ed); + ed_addr); /* Enable the Control list. */ control |= 1 << 4; @@ -424,9 +488,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, { grub_uint8_t errcode; grub_ohci_td_t tderr; + grub_uint32_t td_err_addr; - tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o, - GRUB_OHCI_REG_DONEHEAD); + td_err_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD); + + tderr = (grub_ohci_td_t) ((char *) td_list + + (td_err_addr - td_list_addr)); errcode = tderr->token >> 28; switch (errcode) @@ -519,8 +586,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); /* XXX */ - grub_free (td_list); - grub_free (ed); + grub_dma_free (td_list_chunk); + grub_dma_free (ed_chunk); return err; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 947f2367b..6e47c38ef 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -380,7 +380,7 @@ 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_uint32_t data) { grub_uhci_td_t td; static const unsigned int tf[] = { 0x69, 0xE1, 0x2D }; @@ -398,7 +398,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, } grub_dprintf ("uhci", - "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n", + "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=0x%x td=%p\n", endp, type, addr, toggle, size, data, td); /* Don't point to any TD, just terminate. */ @@ -418,7 +418,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, td->token = ((size << 21) | (toggle << 19) | (endp << 15) | (addr << 8) | tf[type]); - td->buffer = (grub_uint32_t) data; + td->buffer = data; return td; } diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 09e7af83e..f6d3d30f9 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -29,30 +30,59 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t request, grub_uint16_t value, grub_uint16_t index, - grub_size_t size, char *data) + grub_size_t size0, char *data_in) { int i; grub_usb_transfer_t transfer; int datablocks; - struct grub_usb_packet_setup setupdata; + volatile struct grub_usb_packet_setup *setupdata; + grub_uint32_t setupdata_addr; grub_usb_err_t err; unsigned int max; + struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk; + volatile char *data; + grub_uint32_t data_addr; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size ? : 16); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + grub_memcpy ((char *) data, data_in, size); 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)); + transfer = grub_malloc (sizeof (*transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata)); + if (! setupdata_chunk) + { + grub_free (transfer); + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata = grub_dma_get_virt (setupdata_chunk); + setupdata_addr = grub_dma_get_phys (setupdata_chunk); /* Determine the maximum packet size. */ - if (dev->initialized) + if (dev->initialized && dev->descdev.maxsize0) max = dev->descdev.maxsize0; else max = 64; + grub_dprintf ("usb", "transfer = %p, dev = %p\n", transfer, dev); + datablocks = (size + max - 1) / max; /* XXX: Discriminate between different types of control @@ -71,18 +101,20 @@ grub_usb_control_msg (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (setupdata_chunk); + grub_dma_free (data_chunk); return grub_errno; } /* Build a Setup packet. XXX: Endianness. */ - setupdata.reqtype = reqtype; - setupdata.request = request; - setupdata.value = value; - setupdata.index = index; - setupdata.length = size; - transfer->transactions[0].size = sizeof (setupdata); + 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].data = setupdata_addr; transfer->transactions[0].toggle = 0; /* Now the data... XXX: Is this the right way to transfer control @@ -99,13 +131,13 @@ grub_usb_control_msg (grub_usb_device_t dev, tr->pid = GRUB_USB_TRANSFER_TYPE_IN; else tr->pid = GRUB_USB_TRANSFER_TYPE_OUT; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= max; } /* End with an empty OUT transaction. */ transfer->transactions[datablocks + 1].size = 0; - transfer->transactions[datablocks + 1].data = NULL; + transfer->transactions[datablocks + 1].data = 0; if (reqtype & 128) transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; else @@ -117,13 +149,17 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + grub_dma_free (setupdata_chunk); + + grub_memcpy (data_in, (char *) data, size0); return err; } static grub_usb_err_t grub_usb_bulk_readwrite (grub_usb_device_t dev, - int endpoint, grub_size_t size, char *data, + int endpoint, grub_size_t size0, char *data_in, grub_transfer_type_t type) { int i; @@ -132,6 +168,19 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, unsigned int max; grub_usb_err_t err; int toggle = dev->toggle[endpoint]; + volatile char *data; + grub_uint32_t data_addr; + struct grub_pci_dma_chunk *data_chunk; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + if (type == GRUB_USB_TRANSFER_TYPE_OUT) + grub_memcpy ((char *) data, data_in, size); /* Use the maximum packet size given in the endpoint descriptor. */ if (dev->initialized) @@ -150,7 +199,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, /* Create a transfer. */ transfer = grub_malloc (sizeof (struct grub_usb_transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; @@ -167,6 +219,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (data_chunk); return grub_errno; } @@ -181,7 +234,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, tr->toggle = toggle; toggle = toggle ? 0 : 1; tr->pid = type; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= tr->size; } @@ -191,6 +244,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + + if (type == GRUB_USB_TRANSFER_TYPE_IN) + grub_memcpy (data_in, (char *) data, size0); return err; } diff --git a/conf/i386.rmk b/conf/i386.rmk index 02ce39817..73e818f9e 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -56,6 +56,12 @@ pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cs5536.mod +pkglib_MODULES += cs5536.mod +cs5536_mod_SOURCES = bus/cs5536.c +cs5536_mod_CFLAGS = $(COMMON_CFLAGS) +cs5536_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For lspci.mod pkglib_MODULES += lspci.mod lspci_mod_SOURCES = commands/lspci.c diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 5ce8ede9d..2468985c5 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -4,7 +4,8 @@ target_machine=yeeloong COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 -kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h +kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h \ + bitmap_scale.h bufio.h cs5536.h machine/pci.h include $(srcdir)/conf/mips.mk @@ -26,6 +27,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ + bus/cs5536.c \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) @@ -69,5 +71,35 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For usb.mod +pkglib_MODULES += 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 +pkglib_MODULES += usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +pkglib_MODULES += ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +pkglib_MODULES += usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +pkglib_MODULES += usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h new file mode 100644 index 000000000..cd17e11fc --- /dev/null +++ b/include/grub/cs5536.h @@ -0,0 +1,190 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_CS5536_HEADER +#define GRUB_CS5536_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#define GRUB_CS5536_PCIID 0x208f1022 +#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 +#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 +#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc +#define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008 +#define GRUB_CS5536_MSR_SMB_BAR 0x8000000b + +#define GRUB_CS5536_SMBUS_REGS_SIZE 8 +#define GRUB_CS5536_GPIO_REGS_SIZE 256 +#define GRUB_CS5536_MFGPT_REGS_SIZE 64 +#define GRUB_CS5536_IRQ_MAP_REGS_SIZE 32 +#define GRUB_CS5536_PM_REGS_SIZE 128 +#define GRUB_CS5536_ACPI_REGS_SIZE 32 + +#define GRUB_CS5536_USB_OPTION_REGS_SIZE 0x1c +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX 1 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK 0x03 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC 0x02 + +#define GRUB_CS5536_DESTINATION_GLIU 0 +#define GRUB_CS5536_DESTINATION_GLPCI_SB 1 +#define GRUB_CS5536_DESTINATION_USB 2 +#define GRUB_CS5536_DESTINATION_IDE 3 +#define GRUB_CS5536_DESTINATION_DD 4 +#define GRUB_CS5536_DESTINATION_ACC 5 +#define GRUB_CS5536_DESTINATION_GLCP 7 + +#define GRUB_CS5536_P2D_DEST_SHIFT 61 +#define GRUB_CS5536_P2D_LOG_ALIGN 12 +#define GRUB_CS5536_P2D_ALIGN (1 << GRUB_CS5536_P2D_LOG_ALIGN) +#define GRUB_CS5536_P2D_BASE_SHIFT 20 +#define GRUB_CS5536_P2D_MASK_SHIFT 0 + +#define GRUB_CS5536_MSR_GL_IOD_START 0x000100e0 +#define GRUB_CS5536_IOD_DEST_SHIFT 61 +#define GRUB_CS5536_IOD_BASE_SHIFT 20 +#define GRUB_CS5536_IOD_MASK_SHIFT 0 +#define GRUB_CS5536_IOD_ADDR_MASK 0xfffff + +#define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c +#define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d +#define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e +#define GRUB_CS5536_MSR_PM_BAR 0x8000000f +#define GRUB_CS5536_MSR_DIVIL_LEG_IO 0x80000014 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 0x00000001 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1 0x00000002 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 0x10000000 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP 0x04000000 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK 0x80000024 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK 0x80000025 +#define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002 +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL 0x8000004e +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE 0x80 + +#define GRUB_CS5536_MSR_USB_OHCI_BASE 0x40000008 +#define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009 +#define GRUB_CS5536_MSR_USB_CONTROLLER_BASE 0x4000000a +#define GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE 0x4000000b +#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0x00ffffff00ULL +#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x0400000000ULL +#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x0200000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_ENABLED 0x0800000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_STATUS 0x1000000000ULL +#define GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40 + +#define GRUB_CS5536_MSR_IDE_IO_BAR 0x60000008 +#define GRUB_CS5536_MSR_IDE_IO_BAR_UNITS 1 +#define GRUB_CS5536_MSR_IDE_IO_BAR_ADDR_MASK 0xfffffff0 +#define GRUB_CS5536_MSR_IDE_CFG 0x60000010 +#define GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE 2 +#define GRUB_CS5536_MSR_IDE_TIMING 0x60000012 +#define GRUB_CS5536_MSR_IDE_TIMING_PIO0 0x98 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT 16 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING 0x60000013 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 0x99 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT 6 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT 4 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 2 + +#define GRUB_CS5536_MSR_GL_PCI_CTRL 0x00000010 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE 1 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE 2 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT 35 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT 60 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT 56 + +#define GRUB_CS5536_MSR_GL_REGIONS_START 0x00000020 +#define GRUB_CS5536_MSR_GL_REGIONS_NUM 16 +#define GRUB_CS5536_MSR_GL_REGION_ENABLE 1 +#define GRUB_CS5536_MSR_GL_REGION_IO 0x100000000ULL +#define GRUB_CS5536_MSR_GL_REGION_BASE_MASK 0xfffff000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT 12 +#define GRUB_CS5536_MSR_GL_REGION_TOP_MASK 0xfffff00000000000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT 44 + +#define GRUB_CS5536_MSR_GL_P2D_START 0x00010020 + +#define GRUB_CS5536_SMB_REG_DATA 0x0 +#define GRUB_CS5536_SMB_REG_STATUS 0x1 +#define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) +#define GRUB_CS5536_SMB_REG_STATUS_BER (1 << 5) +#define GRUB_CS5536_SMB_REG_STATUS_NACK (1 << 4) +#define GRUB_CS5536_SMB_REG_CTRL1 0x3 +#define GRUB_CS5536_SMB_REG_CTRL1_START 0x01 +#define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02 +#define GRUB_CS5536_SMB_REG_CTRL1_ACK 0x10 +#define GRUB_CS5536_SMB_REG_ADDR 0x4 +#define GRUB_CS5536_SMB_REG_ADDR_MASTER 0x0 +#define GRUB_CS5536_SMB_REG_CTRL2 0x5 +#define GRUB_CS5536_SMB_REG_CTRL2_ENABLE 0x1 +#define GRUB_CS5536_SMB_REG_CTRL3 0x6 + +#ifdef ASM_FILE +#define GRUB_ULL(x) x +#else +#define GRUB_ULL(x) x ## ULL +#endif + +#define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8) +#define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000) +#define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000) +#define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK) + +/* PMON-compatible LBARs. */ +#define GRUB_CS5536_LBAR_GPIO 0xb000 +#define GRUB_CS5536_LBAR_ACC 0xb200 +#define GRUB_CS5536_LBAR_PM 0xb280 +#define GRUB_CS5536_LBAR_MFGPT 0xb300 +#define GRUB_CS5536_LBAR_ACPI 0xb340 +#define GRUB_CS5536_LBAR_IRQ_MAP 0xb360 +#define GRUB_CS5536_LBAR_IDE 0xb380 +#define GRUB_CS5536_LBAR_SMBUS 0xb390 + +#define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) +#define GRUB_GPIO_REG_OUT_EN 0x4 +#define GRUB_GPIO_REG_OUT_AUX1 0x10 +#define GRUB_GPIO_REG_IN_EN 0x20 +#define GRUB_GPIO_REG_IN_AUX1 0x34 + +#ifndef ASM_FILE +int EXPORT_FUNC (grub_cs5536_find) (grub_pci_device_t *devp); + +grub_uint64_t EXPORT_FUNC (grub_cs5536_read_msr) (grub_pci_device_t dev, + grub_uint32_t addr); +void EXPORT_FUNC (grub_cs5536_write_msr) (grub_pci_device_t dev, + grub_uint32_t addr, + grub_uint64_t val); +grub_err_t grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res); +grub_err_t EXPORT_FUNC (grub_cs5536_read_spd) (grub_port_t smbbase, + grub_uint8_t dev, + struct grub_smbus_spd *res); +grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase); +grub_err_t EXPORT_FUNC (grub_cs5536_init_smbus) (grub_pci_device_t dev, + grub_uint16_t divisor, + grub_port_t *smbbase); + +void grub_cs5536_init_geode (grub_pci_device_t dev); +#endif + +#endif diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index bab42adb6..795dec58b 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -80,7 +80,7 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), static inline void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - void *mem __attribute__ ((unused)), + volatile void *mem __attribute__ ((unused)), grub_size_t size __attribute__ ((unused))) { } diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index c7bd31d4f..199bac048 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -19,16 +19,30 @@ #ifndef GRUB_MACHINE_PCI_H #define GRUB_MACHINE_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif + +#define GRUB_YEELOONG_OHCI_PCIID 0x00351033 +#define GRUB_YEELOONG_EHCI_PCIID 0x00e01033 +#define GRUB_YEELOONG_OHCI_GHOST_FUNCTION 4 +#define GRUB_YEELOONG_EHCI_GHOST_FUNCTION 5 #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 -#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 -#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 -#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) +#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 +#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000 + +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR 0xbfe00118 + +#ifndef ASM_FILE +#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) \ + GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) +#endif #define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 #define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) @@ -46,6 +60,7 @@ #define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000 #define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 +#ifndef ASM_FILE static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { @@ -95,11 +110,12 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) } volatile void * -grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), - grub_addr_t base, grub_size_t size); +EXPORT_FUNC (grub_pci_device_map_range) (grub_pci_device_t dev, + grub_addr_t base, grub_size_t size); void -grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - volatile void *mem, - grub_size_t size __attribute__ ((unused))); +EXPORT_FUNC (grub_pci_device_unmap_range) (grub_pci_device_t dev, + volatile void *mem, + grub_size_t size); +#endif #endif /* GRUB_MACHINE_PCI_H */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 89bd1034a..e6d6488f0 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -19,8 +19,10 @@ #ifndef GRUB_PCI_H #define GRUB_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif #define GRUB_PCI_ADDR_SPACE_MASK 0x01 #define GRUB_PCI_ADDR_SPACE_MEMORY 0x00 @@ -66,6 +68,20 @@ #define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MAX_LAT 0x3f +#define GRUB_PCI_COMMAND_IO_ENABLED 0x0001 +#define GRUB_PCI_COMMAND_MEM_ENABLED 0x0002 +#define GRUB_PCI_COMMAND_BUS_MASTER 0x0004 +#define GRUB_PCI_COMMAND_PARITY_ERROR 0x0040 +#define GRUB_PCI_COMMAND_SERR_ENABLE 0x0100 + +#define GRUB_PCI_STATUS_CAPABILITIES 0x0010 +#define GRUB_PCI_STATUS_66MHZ_CAPABLE 0x0020 +#define GRUB_PCI_STATUS_FAST_B2B_CAPABLE 0x0080 + +#define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9 +#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 + +#ifndef ASM_FILE typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_MACHINE_EMU @@ -107,4 +123,14 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); +struct grub_pci_dma_chunk; + +struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, + grub_size_t size); +void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); +volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); +grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); + +#endif + #endif /* GRUB_PCI_H */ diff --git a/include/grub/smbus.h b/include/grub/smbus.h new file mode 100644 index 000000000..0b8e6718f --- /dev/null +++ b/include/grub/smbus.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_SMBUS_HEADER +#define GRUB_SMBUS_HEADER 1 + +#define GRUB_SMB_RAM_START_ADDR 0x50 +#define GRUB_SMB_RAM_NUM_MAX 0x08 + +#define GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR 2 +#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8 +#define GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR 17 +#define GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR 3 +#define GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR 4 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_ADDR 5 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK 0x7 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR 18 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE 5 +#define GRUB_SMBUS_SPD_MEMORY_TRAS_ADDR 30 +#define GRUB_SMBUS_SPD_MEMORY_TRTP_ADDR 38 + +#ifndef ASM_FILE + +struct grub_smbus_spd +{ + grub_uint8_t written_size; + grub_uint8_t log_total_flash_size; + grub_uint8_t memory_type; + union + { + grub_uint8_t unknown[253]; + struct { + grub_uint8_t num_rows; + grub_uint8_t num_columns; + grub_uint8_t num_of_ranks; + grub_uint8_t unused1[12]; + grub_uint8_t num_of_banks; + grub_uint8_t unused2[2]; + grub_uint8_t cas_latency; + grub_uint8_t unused3[9]; + grub_uint8_t rank_capacity; + grub_uint8_t unused4[1]; + grub_uint8_t tras; + grub_uint8_t unused5[7]; + grub_uint8_t trtp; + grub_uint8_t unused6[31]; + grub_uint8_t part_number[18]; + grub_uint8_t unused7[165]; + } ddr2; + }; +}; + +#endif + +#endif diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 7e4a9d7ee..8c739684e 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -37,7 +37,7 @@ struct grub_usb_transaction int size; int toggle; grub_transfer_type_t pid; - char *data; + grub_uint32_t data; }; typedef struct grub_usb_transaction *grub_usb_transaction_t; From 7fd08f56ae0d5f76e5f5c7a184414ae8e0e36a91 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 14:01:38 +0200 Subject: [PATCH 263/503] Shut down OHCI on booting --- bus/usb/ohci.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 7294fe537..29ab5332a 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -654,6 +654,39 @@ grub_ohci_hubports (grub_usb_controller_t dev) return portinfo & 0xFF; } +static grub_err_t +grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) +{ + struct grub_ohci *o; + + for (o = ohci; o; o = o->next) + { + int i, nports = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & 0xff; + for (i = 0; i < nports; i++) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + i, + GRUB_OHCI_CLEAR_PORT_ENABLE); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ohci_restore_hw (void) +{ + struct grub_ohci *o; + + for (o = ohci; o; o = o->next) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); + + return GRUB_ERR_NONE; +} static struct grub_usb_controller_dev usb_controller = @@ -670,9 +703,12 @@ GRUB_MOD_INIT(ohci) { grub_ohci_inithw (); grub_usb_controller_dev_register (&usb_controller); + grub_loader_register_preboot_hook (grub_ohci_fini_hw, grub_ohci_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); } GRUB_MOD_FINI(ohci) { + grub_ohci_fini_hw (0); grub_usb_controller_dev_unregister (&usb_controller); } From 778ff32476c08a69d99e56fbfe9e7494e0c26bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Mon, 31 May 2010 14:11:41 +0200 Subject: [PATCH 264/503] Fix a bunch of problems with USB. --- bus/usb/ohci.c | 342 +++++++++++++++++++++++++++++++--------- bus/usb/uhci.c | 17 +- bus/usb/usb.c | 12 +- bus/usb/usbtrans.c | 5 +- commands/usbtest.c | 2 + disk/scsi.c | 183 +++++++++++++++++++-- disk/usbms.c | 166 ++++++++++++------- include/grub/scsicmd.h | 62 ++++++-- include/grub/usb.h | 9 +- include/grub/usbtrans.h | 6 +- 10 files changed, 637 insertions(+), 167 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 29ab5332a..03768d39e 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -27,6 +27,7 @@ #include #include #include +#include struct grub_ohci_hcca { @@ -96,7 +97,11 @@ typedef enum GRUB_OHCI_REG_FRAME_INTERVAL, GRUB_OHCI_REG_PERIODIC_START = 16, GRUB_OHCI_REG_RHUBA = 18, - GRUB_OHCI_REG_RHUBPORT = 21 + GRUB_OHCI_REG_RHUBPORT = 21, + GRUB_OHCI_REG_LEGACY_CONTROL = 0x100, + GRUB_OHCI_REG_LEGACY_INPUT = 0x104, + GRUB_OHCI_REG_LEGACY_OUTPUT = 0x108, + GRUB_OHCI_REG_LEGACY_STATUS = 0x10c } grub_ohci_reg_t; #define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 @@ -195,7 +200,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if (! o) return 1; - o->iobase = grub_pci_device_map_range (dev, base, 0x100); + o->iobase = grub_pci_device_map_range (dev, base, 0x800); grub_dprintf ("ohci", "base=%p\n", o->iobase); @@ -212,10 +217,48 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, - (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) - & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) - | GRUB_OHCI_RHUB_PORT_ALL_POWERED); + + { + grub_uint32_t control; + /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + if ((control & 0x100) != 0) + { + unsigned i; + grub_dprintf("ohci", "OHCI is owned by SMM\n"); + /* Do change of ownership */ + /* Ownership change request */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, (1<<3)); /* XXX: Magic. */ + /* Waiting for SMM deactivation */ + for (i=0; i < 10; i++) + { + if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & 0x100) == 0) + { + grub_dprintf("ohci", "Ownership changed normally.\n"); + break; + } + grub_millisleep (100); + } + if (i >= 10) + { + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~0x100); + grub_dprintf("ohci", "Ownership changing timeout, change forced !\n"); + } + } + else if (((control & 0x100) == 0) && + ((control & 0xc0) != 0)) /* Not owned by SMM nor reset */ + { + grub_dprintf("ohci", "OHCI is owned by BIOS\n"); + /* Do change of ownership - not implemented yet... */ + /* In fact we probably need to do nothing ...? */ + } + else + { + grub_dprintf("ohci", "OHCI is not owned by SMM nor BIOS\n"); + /* We can setup OHCI. */ + } + } /* Suspend the OHCI by issuing a reset. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ @@ -232,15 +275,58 @@ grub_ohci_pci_iter (grub_pci_device_t dev, GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ + o->hcca->donehead = 0; grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); + /* Misc. pre-sets. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + /* Check OHCI Legacy Support */ + if ((revision & 0x100) != 0) + { + grub_dprintf ("ohci", "Legacy Support registers detected\n"); + grub_dprintf ("ohci", "Current state of legacy control reg.: 0x%04x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)) & ~1); + grub_dprintf ("ohci", "OHCI Legacy Support disabled.\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); + /* Power on all ports */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) + & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) + | GRUB_OHCI_RHUB_PORT_ALL_POWERED); + /* Wait for stable power (100ms) and stable attachment (100ms) */ + /* I.e. minimum wait time should be probably 200ms. */ + /* We assume that device is attached when ohci is loaded. */ + /* Some devices take long time to power-on or indicate attach. */ + /* Here is some experimental value which should probably mostly work. */ + /* Cameras with manual USB mode selection and maybe some other similar + * devices will not work in some cases - they are repowered during + * ownership change and then they are starting slowly and mostly they + * are wanting select proper mode again... + * The same situation can be on computers where BIOS not set-up OHCI + * to be at least powered USB bus (maybe it is Yeelong case...?) + * Possible workaround could be for example some prompt + * for user with confirmation of proper USB device connection. + * Another workaround - "rmmod usbms", "rmmod ohci", proper start + * and configuration of USB device and then "insmod ohci" + * and "insmod usbms". */ + grub_millisleep (500); + /* Link to ohci now that initialisation is successful. */ o->next = ohci; ohci = o; @@ -317,13 +403,29 @@ grub_ohci_transaction (grub_ohci_td_t td, token |= toggle << 24; token |= 1 << 25; + /* Set "Not accessed" error code */ + token |= 15 << 28; + buffer = data; buffer_end = buffer + size - 1; + /* Set correct buffer values in TD if zero transfer occurs */ + if (size) + { + buffer = (grub_uint32_t) data; + buffer_end = buffer + size - 1; + td->buffer = grub_cpu_to_le32 (buffer); + td->buffer_end = grub_cpu_to_le32 (buffer_end); + } + else + { + td->buffer = 0; + td->buffer_end = 0; + } + + /* Set the rest of TD */ 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 @@ -342,7 +444,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint32_t status; grub_uint32_t control; grub_usb_err_t err; - int i; + int i, j; + grub_uint64_t maxtime; + int err_timeout = 0; /* Allocate an Endpoint Descriptor. */ ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); @@ -375,13 +479,25 @@ grub_ohci_transfer (grub_usb_controller_t dev, + (i + 1) * sizeof (td_list[0])); } + /* The last-1 TD token we should change to enable interrupt when TD finishes. + * As OHCI interrupts are disabled, it does only setting of WDH bit in + * HcInterruptStatus register - and that is what we want to safely detect + * normal end of all transactions. */ + td_list[transfer->transcnt - 1].token &= ~(7 << 21); + + td_list[transfer->transcnt].token = 0; + td_list[transfer->transcnt].buffer = 0; + td_list[transfer->transcnt].buffer_end = 0; + td_list[transfer->transcnt].next_td = + (grub_uint32_t) &td_list[transfer->transcnt]; + /* Setup the Endpoint Descriptor. */ /* Set the device address. */ target = transfer->devaddr; - /* Set the endpoint. */ - target |= transfer->endpoint << 7; + /* Set the endpoint. It should be masked, we need 4 bits only. */ + target |= (transfer->endpoint & 15) << 7; /* Set the device speed. */ target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13; @@ -400,6 +516,30 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_dprintf ("ohci", "program OHCI\n"); + /* 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 &= ~(3 << 1); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + + /* Now we should wait for start of next frame. Because we are not using + * interrupt, we reset SF bit and wait when it goes to 1. */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + /* Now it should be safe to change CONTROL and BULK lists. */ + + /* This we do for safety's sake - it should be done in previous call + * of grub_ohci_transfer and nobody should change it in meantime... + * It should be done before start of control or bulk OHCI list. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + /* Program the OHCI to actually transfer. */ switch (transfer->type) { @@ -407,24 +547,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, { 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); - + /* Set BulkList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); /* Enable the Bulk list. */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); control |= 1 << 5; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set BulkListFilled. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); status |= 1 << 2; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); @@ -433,21 +566,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, 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); - + /* Set ControlList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - ed_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); /* Enable the Control list. */ control |= 1 << 4; @@ -465,36 +586,77 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + /* Safety measure to avoid a hang. */ + maxtime = grub_get_time_ms () + 1000; + /* Wait until the transfer is completed or STALLs. */ - while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf)) + do { grub_cpu_idle (); - grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail); + /* Detected a HALT. */ + if (grub_le_to_cpu32 (ed->td_head) & 1) + break; + + if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x2) != 0) + { + if ((grub_le_to_cpu32 (o->hcca->donehead) & ~0xf) + == td_list_addr + (transfer->transcnt - 1) * sizeof (td_list[0])) + break; - /* Detected a STALL. */ - if (ed->td_head & 1) + /* Done Head can be updated on some another place if ED is halted. */ + if (grub_le_to_cpu32 (ed->td_head) & 1) + break; + + /* If there is not HALT in ED, it is not correct, so debug it, reset + * donehead and WDH and continue waiting. */ + grub_dprintf ("ohci", "Incorrect HccaDoneHead=0x%08x\n", + o->hcca->donehead); + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + continue; + } + /* Timeout ? */ + if (grub_get_time_ms () > maxtime) + { + /* Disable the Control and Bulk lists. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~(3 << 4)); + err_timeout = 1; + break; + } + + if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) break; } + while (1); - grub_dprintf ("ohci", "complete\n"); - -/* if (ed->td_head & 1) */ -/* err = GRUB_USB_ERR_STALL; */ -/* else if (ed->td */ - - - if (ed->td_head & 1) + if (err_timeout) + { + err = GRUB_ERR_TIMEOUT; + grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n\t\ttail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); + } + else if (grub_le_to_cpu32 (ed->td_head) & 1) { - grub_uint8_t errcode; - grub_ohci_td_t tderr; grub_uint32_t td_err_addr; + grub_uint8_t errcode; + grub_ohci_td_t tderr = NULL; - td_err_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD); + td_err_addr = (grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf); + if (td_err_addr == 0) + /* If DONEHEAD==0 it means that correct address is in HCCA. + * It should be always now! */ + td_err_addr = (grub_le_to_cpu32 (o->hcca->donehead) & ~0xf); tderr = (grub_ohci_td_t) ((char *) td_list + (td_err_addr - td_list_addr)); - errcode = tderr->token >> 28; + + errcode = grub_le_to_cpu32 (tderr->token) >> 28; + grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode); switch (errcode) { @@ -540,11 +702,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, case 8: /* XXX: Data overrun error. */ err = GRUB_USB_ERR_DATA; + j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); + grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", tderr, j); break; case 9: /* XXX: Data underrun error. */ err = GRUB_USB_ERR_DATA; + grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n", + 1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer)); + j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); + grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", tderr, j); break; case 10: @@ -582,43 +750,73 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Clear BulkListFilled and ControlListFilled. */ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - status &= ~((1 << 2) | (1 << 3)); + status &= ~(3 << 1); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - - /* XXX */ + + /* Set ED to be skipped - for safety */ + ed->target |= grub_cpu_to_le32 (1 << 14); + + /* Now we should wait for start of next frame. + * It is necessary because we will invalidate pointer to ED and it + * can be on OHCI active till SOF! + * Because we are not using interrupt, we reset SF bit and wait when + * it goes to 1. */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + /* Now it should be safe to change CONTROL and BULK lists. */ + + /* Important cleaning. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err); + grub_dma_free (td_list_chunk); grub_dma_free (ed_chunk); return err; } +#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) +#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) +#define GRUB_OHCI_SET_PORT_RESET (1 << 4) +#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) + 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); + grub_dprintf ("ohci", "begin of portstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); - /* 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_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET); + grub_millisleep (50); /* For root hub should be nominaly 50ms */ + + /* End the reset signaling. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE); 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); + if (enable) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_ENABLE); + else + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_CLEAR_PORT_ENABLE); + grub_millisleep (10); + grub_dprintf ("ohci", "end of portstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); + return GRUB_ERR_NONE; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 6e47c38ef..eb533c926 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -174,14 +174,15 @@ grub_uhci_pci_iter (grub_pci_device_t dev, return 1; u->iobase = base & GRUB_UHCI_IOMASK; - grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n", - class, subclass, interf, u->iobase); /* Reserve a page for the frame list. */ u->framelist = grub_memalign (4096, 4096); if (! u->framelist) goto fail; + grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x framelist=%p\n", + class, subclass, interf, u->iobase, u->framelist); + /* 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 @@ -221,6 +222,9 @@ grub_uhci_pci_iter (grub_pci_device_t dev, } #endif + grub_dprintf ("uhci", "QH=%p, TD=%p\n", + u->qh, u->td); + /* Link all Transfer Descriptors in a list of available Transfer Descriptors. */ for (i = 0; i < 256; i++) @@ -441,6 +445,8 @@ grub_uhci_transfer (grub_usb_controller_t dev, if (! qh) return grub_errno; + grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase); + for (i = 0; i < transfer->transcnt; i++) { grub_usb_transaction_t tr = &transfer->transactions[i]; @@ -548,7 +554,8 @@ grub_uhci_transfer (grub_usb_controller_t dev, fail: - grub_dprintf ("uhci", "transaction failed\n"); + if (err != GRUB_USB_ERR_NONE) + grub_dprintf ("uhci", "transaction failed\n"); /* Place the QH back in the free list and deallocate the associated TDs. */ @@ -583,6 +590,8 @@ grub_uhci_portstatus (grub_usb_controller_t dev, unsigned int status; grub_uint64_t endtime; + grub_dprintf ("uhci", "portstatus, iobase:%08x\n", u->iobase); + grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port); if (port == 0) @@ -631,6 +640,8 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port) int reg; unsigned int status; + grub_dprintf ("uhci", "detect_dev, iobase:%08x\n", u->iobase); + if (port == 0) reg = GRUB_UHCI_REG_PORTSC1; else if (port == 1) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 8289185da..7df148333 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -107,7 +107,7 @@ grub_usb_set_configuration (grub_usb_device_t dev, int configuration) { int i; - for (i = 0; i < 16; i++) + for (i = 0; i < 256; i++) dev->toggle[i] = 0; return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT @@ -163,6 +163,16 @@ grub_usb_device_initialize (grub_usb_device_t dev) grub_usb_err_t err; int i; + /* First we have to read first 8 bytes only and determine + * max. size of packet */ + dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */ + err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, + 0, 8, (char *) &dev->descdev); + if (err) + return err; + + /* Now we have valid value in dev->descdev.maxsize0, + * so we can read whole device descriptor */ err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, 0, sizeof (struct grub_usb_desc_device), (char *) &dev->descdev); diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index f6d3d30f9..0bf5ee6de 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -138,7 +138,7 @@ grub_usb_control_msg (grub_usb_device_t dev, /* End with an empty OUT transaction. */ transfer->transactions[datablocks + 1].size = 0; transfer->transactions[datablocks + 1].data = 0; - if (reqtype & 128) + if ((reqtype & 128) && datablocks) transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; else transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN; @@ -148,6 +148,7 @@ grub_usb_control_msg (grub_usb_device_t dev, err = dev->controller.dev->transfer (&dev->controller, transfer); grub_free (transfer->transactions); + grub_free (transfer); grub_dma_free (data_chunk); grub_dma_free (setupdata_chunk); @@ -207,7 +208,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; transfer->size = size - 1; - transfer->endpoint = endpoint; + transfer->endpoint = endpoint & 15; transfer->devaddr = dev->addr; transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->max = max; diff --git a/commands/usbtest.c b/commands/usbtest.c index 191c4e4df..7d1f85cfd 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -148,6 +148,8 @@ usb_iterate (grub_usb_device_t dev) grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); + return 0; + for (i = 0; i < descdev->configcnt; i++) { struct grub_usb_desc_config *config; diff --git a/disk/scsi.c b/disk/scsi.c index eba237287..e8bfb6a3f 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -25,6 +25,7 @@ #include #include #include +#include static grub_scsi_dev_t grub_scsi_dev_list; @@ -50,7 +51,62 @@ grub_scsi_dev_unregister (grub_scsi_dev_t dev) } -/* Determine the the device is removable and the type of the device +/* Check result of previous operation. */ +static grub_err_t +grub_scsi_request_sense (grub_scsi_t scsi) +{ + struct grub_scsi_request_sense rs; + struct grub_scsi_request_sense_data rsd; + grub_err_t err; + + rs.opcode = grub_scsi_cmd_request_sense; + rs.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + rs.reserved1 = 0; + rs.reserved2 = 0; + rs.alloc_length = 0x12; /* XXX: Hardcoded for now */ + rs.control = 0; + grub_memset (rs.pad, 0, sizeof(rs.pad)); + + err = scsi->dev->read (scsi, sizeof (rs), (char *) &rs, + sizeof (rsd), (char *) &rsd); + if (err) + return err; + + return GRUB_ERR_NONE; +} +/* Self commenting... */ +static grub_err_t +grub_scsi_test_unit_ready (grub_scsi_t scsi) +{ + struct grub_scsi_test_unit_ready tur; + grub_err_t err; + grub_err_t err_sense; + + tur.opcode = grub_scsi_cmd_test_unit_ready; + tur.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + tur.reserved1 = 0; + tur.reserved2 = 0; + tur.reserved3 = 0; + tur.control = 0; + grub_memset (tur.pad, 0, sizeof(tur.pad)); + + err = scsi->dev->read (scsi, sizeof (tur), (char *) &tur, + 0, NULL); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + if (err) + return err; + + return GRUB_ERR_NONE; +} + +/* Determine if the device is removable and the type of the device SCSI. */ static grub_err_t grub_scsi_inquiry (grub_scsi_t scsi) @@ -58,15 +114,26 @@ grub_scsi_inquiry (grub_scsi_t scsi) struct grub_scsi_inquiry iq; struct grub_scsi_inquiry_data iqd; grub_err_t err; + grub_err_t err_sense; iq.opcode = grub_scsi_cmd_inquiry; iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + iq.page = 0; iq.reserved = 0; iq.alloc_length = 0x24; /* XXX: Hardcoded for now */ - iq.reserved2 = 0; + iq.control = 0; + grub_memset (iq.pad, 0, sizeof(iq.pad)); err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq, sizeof (iqd), (char *) &iqd); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + if (err) return err; @@ -83,13 +150,27 @@ 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; + grub_err_t err_sense; rc.opcode = grub_scsi_cmd_read_capacity; rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - grub_memset (rc.reserved, 0, sizeof (rc.reserved)); - + rc.logical_block_addr = 0; + rc.reserved1 = 0; + rc.reserved2 = 0; + rc.PMI = 0; + rc.control = 0; + rc.pad = 0; + err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, sizeof (rcd), (char *) &rcd); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; +/* err_sense is ignored for now and Request Sense Data also... */ + if (err) return err; @@ -107,6 +188,8 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_read10 rd; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -118,7 +201,16 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector, rd.reserved2 = 0; rd.pad = 0; - return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } /* Send a SCSI request for DISK: read SIZE sectors starting with @@ -129,6 +221,8 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_read12 rd; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -139,7 +233,16 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector, rd.reserved = 0; rd.control = 0; - return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } #if 0 @@ -151,6 +254,8 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_write10 wr; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -162,7 +267,16 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector, wr.reserved2 = 0; wr.pad = 0; - return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } /* Send a SCSI request for DISK: write the data stored in BUF to SIZE @@ -172,7 +286,9 @@ 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; + struct grub_scsi_write12 wr; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -181,9 +297,18 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, wr.lba = grub_cpu_to_be32 (sector); wr.size = grub_cpu_to_be32 (size); wr.reserved = 0; - wr.pad = 0; + wr.control = 0; - return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } #endif @@ -235,6 +360,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) grub_err_t err; int len; int lun; + grub_uint64_t maxtime; scsi = grub_malloc (sizeof (*scsi)); if (! scsi) @@ -292,6 +418,31 @@ grub_scsi_open (const char *name, grub_disk_t disk) else disk->has_partitions = 1; + + /* According to USB MS tests specification, issue Test Unit Ready + * until OK */ + maxtime = grub_get_time_ms () + 1000; + do + { + /* Timeout is necessary - for example in case when we have + * universal card reader with more LUNs and we have only + * one card inserted (or none), so only one LUN (or none) + * will be ready - and we want not to hang... */ + if (grub_get_time_ms () > maxtime) + { + err = GRUB_ERR_READ_ERROR; + grub_free (scsi); + grub_dprintf ("scsi", "LUN is not ready - timeout\n"); + return err; + } + err = grub_scsi_test_unit_ready (scsi); + } + while (err == GRUB_ERR_READ_ERROR); + /* Reset grub_errno ! + * It is set to some error code in loop before... */ + grub_errno = GRUB_ERR_NONE; + + /* Read capacity of media */ err = grub_scsi_read_capacity (scsi); if (err) { @@ -302,12 +453,14 @@ grub_scsi_open (const char *name, grub_disk_t disk) /* 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); + disk->total_sectors = ((grub_uint64_t)scsi->size + * (grub_uint64_t)scsi->blocksize) + >> GRUB_DISK_SECTOR_BITS; - grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n", - (unsigned long long) disk->total_sectors, - scsi->blocksize); + grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n", + scsi->size, scsi->blocksize); + grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n", + disk->total_sectors); return GRUB_ERR_NONE; } diff --git a/disk/usbms.c b/disk/usbms.c index 8554b224f..7b719fb84 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -84,7 +84,8 @@ grub_usbms_finddevs (void) struct grub_usb_desc_device *descdev = &usbdev->descdev; int i; - if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0) + if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 + || descdev->configcnt == 0) return 0; /* XXX: Just check configuration 0 for now. */ @@ -93,19 +94,31 @@ grub_usbms_finddevs (void) struct grub_usbms_dev *usbms; struct grub_usb_desc_if *interf; int j; - grub_uint8_t luns; + grub_uint8_t luns = 0; + + grub_dprintf ("usbms", "alive\n"); interf = usbdev->config[0].interf[i].descif; /* If this is not a USB Mass Storage device with a supported protocol, just skip it. */ + grub_dprintf ("usbms", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", + i, interf->class, interf->subclass, interf->protocol); + if (interf->class != GRUB_USB_CLASS_MASS_STORAGE - || interf->subclass != GRUB_USBMS_SUBCLASS_BULK + || ( interf->subclass != GRUB_USBMS_SUBCLASS_BULK && + /* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */ + interf->subclass != GRUB_USBMS_SUBCLASS_RBC && + interf->subclass != GRUB_USBMS_SUBCLASS_MMC2 && + interf->subclass != GRUB_USBMS_SUBCLASS_UFI && + interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 ) || interf->protocol != GRUB_USBMS_PROTOCOL_BULK) { continue; } + grub_dprintf ("usbms", "alive\n"); + devcnt++; usbms = grub_zalloc (sizeof (struct grub_usbms_dev)); if (! usbms) @@ -114,6 +127,8 @@ grub_usbms_finddevs (void) usbms->dev = usbdev; usbms->interface = i; + grub_dprintf ("usbms", "alive\n"); + /* Iterate over all endpoints of this interface, at least a IN and OUT bulk endpoint are required. */ for (j = 0; j < interf->endpointcnt; j++) @@ -125,14 +140,16 @@ grub_usbms_finddevs (void) { /* Bulk IN endpoint. */ usbms->in = endp; - grub_usb_clear_halt (usbdev, endp->endp_addr & 128); + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ 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); + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ usbms->out_maxsz = endp->maxpacket; } } @@ -143,51 +160,63 @@ grub_usbms_finddevs (void) return 0; } + grub_dprintf ("usbms", "alive\n"); + + /* XXX: Activate the first configuration. */ + grub_usb_set_configuration (usbdev, 1); + /* 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); + grub_usb_clear_halt (usbdev, usbms->in->endp_addr); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr); } - /* Just set the amount of LUNs to one. */ grub_errno = GRUB_ERR_NONE; usbms->luns = 1; } else - usbms->luns = luns; + /* luns = 0 means one LUN with ID 0 present ! */ + /* We get from device not number of LUNs but highest + * LUN number. LUNs are numbered from 0, + * i.e. number of LUNs is luns+1 ! */ + usbms->luns = luns + 1; - /* 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; + grub_dprintf ("usbms", "alive\n"); usbms->next = grub_usbms_dev_list; grub_usbms_dev_list = usbms; - /* XXX: Activate the first configuration. */ - grub_usb_set_configuration (usbdev, 1); - +#if 0 /* All this part should be probably deleted. + * This make trouble on some devices if they are not in + * Phase Error state - and there they should be not in such state... + * Bulk only mass storage reset procedure should be used only + * on place and in time when it is really necessary. */ + /* Reset recovery procedure */ /* Bulk-Only Mass Storage Reset, after the reset commands will be accepted. */ grub_usbms_reset (usbdev, i); + grub_usb_clear_halt (usbdev, usbms->in->endp_addr); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr); +#endif return 0; } + grub_dprintf ("usbms", "alive\n"); return 0; } + grub_dprintf ("usbms", "alive\n"); grub_usb_iterate (usb_iterate); + grub_dprintf ("usbms", "alive\n"); + } @@ -225,6 +254,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, static grub_uint32_t tag = 0; grub_usb_err_t err = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; + grub_size_t i; retry: retrycnt--; @@ -237,73 +267,89 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, 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.lun = scsi->lun; /* In USB MS CBW are LUN bits on another place than in SCSI CDB, both should be set correctly. */ cbw.length = cmdsize; grub_memcpy (cbw.cbwcb, cmd, cmdsize); + + /* Debug print of CBW content. */ + grub_dprintf ("usb", "CBW: sign=0x%08x tag=0x%08x len=0x%08x\n", + cbw.signature, cbw.tag, cbw.transfer_length); + grub_dprintf ("usb", "CBW: flags=0x%02x lun=0x%02x CB_len=0x%02x\n", + cbw.flags, cbw.lun, cbw.length); + grub_dprintf ("usb", "CBW: cmd:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + cbw.cbwcb[ 0], cbw.cbwcb[ 1], cbw.cbwcb[ 2], cbw.cbwcb[ 3], + cbw.cbwcb[ 4], cbw.cbwcb[ 5], cbw.cbwcb[ 6], cbw.cbwcb[ 7], + cbw.cbwcb[ 8], cbw.cbwcb[ 9], cbw.cbwcb[10], cbw.cbwcb[11], + cbw.cbwcb[12], cbw.cbwcb[13], cbw.cbwcb[14], cbw.cbwcb[15]); - /* Write the request. */ - err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15, + /* Write the request. + * XXX: Error recovery is maybe still not fully correct. */ + err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, sizeof (cbw), (char *) &cbw); if (err) { if (err == GRUB_USB_ERR_STALL) { + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); 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) + /* Read/write the data, (maybe) according to specification. */ + if (size && (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"); - } + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); + grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); + if (err) goto CheckCSW; + /* Debug print of received data. */ + grub_dprintf ("usb", "buf:\n"); + if (size <= 64) + for (i=0; idev, dev->in->endp_addr & 15, size, buf); + err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, 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"); - } + grub_dprintf ("usb", "buf:\n"); + /* Debug print of sent data. */ + if (size <= 256) + for (i=0; idev, dev->in->endp_addr & 15, - sizeof (status), (char *) &status); + /* Read the status - (maybe) according to specification. */ +CheckCSW: + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + sizeof (status), (char *) &status); if (err) { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + sizeof (status), (char *) &status); + if (err) + { /* Bulk-only 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); goto retry; - } - return grub_error (GRUB_ERR_READ_ERROR, - "can't read status from USB Mass Storage device"); + } } - /* XXX: Magic and check this code. */ + /* Debug print of CSW content. */ + grub_dprintf ("usb", "CSW: sign=0x%08x tag=0x%08x resid=0x%08x\n", + status.signature, status.tag, status.residue); + grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status); + + /* If phase error, do bulk-only reset device. */ 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); diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h index 40f237a17..f9a7cb200 100644 --- a/include/grub/scsicmd.h +++ b/include/grub/scsicmd.h @@ -25,14 +25,26 @@ #define GRUB_SCSI_REMOVABLE_BIT 7 #define GRUB_SCSI_LUN_SHIFT 5 +struct grub_scsi_test_unit_ready +{ + grub_uint8_t opcode; + grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t reserved3; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ +} __attribute__((packed)); + 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]; + grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 EVPD */ + grub_uint8_t page; /* page code if EVPD=1 */ + grub_uint8_t reserved; + grub_uint8_t alloc_length; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ } __attribute__((packed)); struct grub_scsi_inquiry_data @@ -47,12 +59,42 @@ struct grub_scsi_inquiry_data char prodrev[4]; } __attribute__((packed)); +struct grub_scsi_request_sense +{ + grub_uint8_t opcode; + grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t alloc_length; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ +} __attribute__((packed)); + +struct grub_scsi_request_sense_data +{ + grub_uint8_t error_code; /* 7 Valid, 6-0 Err. code */ + grub_uint8_t segment_number; + grub_uint8_t sense_key; /*7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */ + grub_uint32_t information; + grub_uint8_t additional_sense_length; + grub_uint32_t cmd_specific_info; + grub_uint8_t additional_sense_code; + grub_uint8_t additional_sense_code_qualifier; + grub_uint8_t field_replaceable_unit_code; + grub_uint8_t sense_key_specific[3]; + /* there can be additional sense field */ +} __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]; + grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 reserved */ + grub_uint32_t logical_block_addr; /* only if PMI=1 */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t PMI; + grub_uint8_t control; + grub_uint16_t pad; /* To be ATAPI compatible */ } __attribute__((packed)); struct grub_scsi_read_capacity_data @@ -106,11 +148,13 @@ struct grub_scsi_write12 typedef enum { grub_scsi_cmd_inquiry = 0x12, + grub_scsi_cmd_test_unit_ready = 0x00, 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_write12 = 0xaa, + grub_scsi_cmd_request_sense = 0x03 } grub_scsi_cmd_t; typedef enum diff --git a/include/grub/usb.h b/include/grub/usb.h index dc90e7879..cbbc39303 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -156,7 +156,7 @@ struct grub_usb_device int initialized; /* Data toggle values (used for bulk transfers only). */ - int toggle[16]; + int toggle[256]; /* Device-specific data. */ void *data; @@ -184,7 +184,12 @@ typedef enum typedef enum { - GRUB_USBMS_SUBCLASS_BULK = 0x06 + GRUB_USBMS_SUBCLASS_BULK = 0x06, + /* Experimental support for non-pure SCSI devices */ + GRUB_USBMS_SUBCLASS_RBC = 0x01, + GRUB_USBMS_SUBCLASS_MMC2 = 0x02, + GRUB_USBMS_SUBCLASS_UFI = 0x04, + GRUB_USBMS_SUBCLASS_SFF8070 = 0x05 } grub_usbms_subclass_t; typedef enum diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 8c739684e..cd818e1fc 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -86,9 +86,9 @@ typedef struct grub_usb_transfer *grub_usb_transfer_t; #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_FEATURE_ENDP_HALT 0x00 +#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01 +#define GRUB_USB_FEATURE_TEST_MODE 0x02 #define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) #define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) From c837af3f38882470ea30d4392427d17c5132cdea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:23:51 +0200 Subject: [PATCH 265/503] * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check 64-bit address as signed on MIPS. --- ChangeLog | 5 +++++ loader/multiboot_elfxx.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5072a6026..c6edd3ac3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check + 64-bit address as signed on MIPS. + 2010-05-28 Colin Watson * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not diff --git a/loader/multiboot_elfxx.c b/loader/multiboot_elfxx.c index 92a52d3a8..78b7c542c 100644 --- a/loader/multiboot_elfxx.c +++ b/loader/multiboot_elfxx.c @@ -74,7 +74,11 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) 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"); -#ifdef MULTIBOOT_LOAD_ELF64 +#if defined (MULTIBOOT_LOAD_ELF64) && defined (__mips) + /* We still in 32-bit mode. */ + if (ehdr->e_entry < 0xffffffff80000000ULL) + return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); +#else /* We still in 32-bit mode. */ if (ehdr->e_entry > 0xffffffff) return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); From 7620e7debd2a54cb29bab9f74c49f45ec76dcf9d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:40:42 +0200 Subject: [PATCH 266/503] * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ commands/setpci.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c6edd3ac3..5bbb1c12f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check diff --git a/commands/setpci.c b/commands/setpci.c index fbc7c214e..aa09f5bbb 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -96,7 +96,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (check_device && grub_pci_get_device (dev) != device) return 0; - if (check_function && grub_pci_get_function (dev) != device) + if (check_function && grub_pci_get_function (dev) != function) return 0; addr = grub_pci_make_address (dev, regaddr); From 5629316656a33304ac15364bf09b6f1d6800b447 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:43:28 +0200 Subject: [PATCH 267/503] * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect addition of dest. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ loader/multiboot_mbi2.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5bbb1c12f..aa9363dd7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect + addition of dest. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c index 7e9cebe49..c9e52e51f 100644 --- a/loader/multiboot_mbi2.c +++ b/loader/multiboot_mbi2.c @@ -496,7 +496,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, = (struct multiboot_tag_module *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_MODULE; tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size; - tag->mod_start = dest + cur->start; + tag->mod_start = cur->start; tag->mod_end = tag->mod_start + cur->size; grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); From c2ffc8e956be5df59fd2fa96c4102e02a78f1799 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:46:16 +0200 Subject: [PATCH 268/503] * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ normal/main.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aa9363dd7..2d9015cfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect diff --git a/normal/main.c b/normal/main.c index 4ed17e82c..14a25032f 100644 --- a/normal/main.c +++ b/normal/main.c @@ -204,7 +204,7 @@ grub_normal_add_menu_entry (int argc, const char **args, for (i = 0; i < argc; i++) { /* Capture arguments. */ - if (grub_strncmp ("--", args[i], 2) == 0) + if (grub_strncmp ("--", args[i], 2) == 0 && i + 1 < argc) { const char *arg = &args[i][2]; From dfbfe00473ad0edb62cc3d0958949578d4a8ecd3 Mon Sep 17 00:00:00 2001 From: Jiro SEKIBA Date: Mon, 31 May 2010 20:49:42 +0200 Subject: [PATCH 269/503] * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. * fs/nilfs.c: Support 2nd super block in case 1st one is accidently corrupted or not synced properly. --- ChangeLog | 6 ++++ fs/nilfs2.c | 67 +++++++++++++++++++++++++++++++++++++-------- include/grub/disk.h | 3 ++ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d9015cfb..a35843554 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Jiro SEKIBA + + * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. + * fs/nilfs.c: Support 2nd super block in case 1st one is accidently + corrupted or not synced properly. + 2010-05-31 Vladimir Serbinenko * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. diff --git a/fs/nilfs2.c b/fs/nilfs2.c index 7e0415d12..5d32f5f88 100644 --- a/fs/nilfs2.c +++ b/fs/nilfs2.c @@ -49,6 +49,13 @@ #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) #define NILFS_BTREE_LEVEL_MAX 14 +/* nilfs 1st super block posission from beginning of the partition + in 512 block size */ +#define NILFS_1ST_SUPER_BLOCK 2 +/* nilfs 2nd super block posission from end of the partition + in 512 block size */ +#define NILFS_2ND_SUPER_BLOCK 8 + struct grub_nilfs2_inode { grub_uint64_t i_blocks; @@ -703,6 +710,52 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp) return 1; } +static grub_err_t +grub_nilfs2_load_sb (struct grub_nilfs2_data *data) +{ + grub_disk_t disk = data->disk; + struct grub_nilfs2_super_block sb2; + grub_uint64_t partition_size; + int valid[2]; + int swp = 0; + + /* Read first super block. */ + grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &data->sblock); + /* Make sure if 1st super block is valid. */ + valid[0] = grub_nilfs2_valid_sb (&data->sblock); + + partition_size = grub_disk_get_size (disk); + if (partition_size != GRUB_DISK_SIZE_UNKNOWN) + { + /* Read second super block. */ + grub_disk_read (disk, partition_size - NILFS_2ND_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &sb2); + /* Make sure if 2nd super block is valid. */ + valid[1] = grub_nilfs2_valid_sb (&sb2); + } + else + /* 2nd super block may not exist, so it's invalid. */ + valid[1] = 0; + + + + if (!valid[0] && !valid[1]) + return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + + swp = valid[1] && (!valid[0] || + grub_le_to_cpu64 (data->sblock.s_last_cno) < + grub_le_to_cpu64 (sb2.s_last_cno)); + + /* swap if first super block is invalid or older than second one. */ + if (swp) + grub_memcpy (&data->sblock, &sb2, + sizeof (struct grub_nilfs2_super_block)); + + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + static struct grub_nilfs2_data * grub_nilfs2_mount (grub_disk_t disk) { @@ -717,19 +770,13 @@ grub_nilfs2_mount (grub_disk_t disk) if (!data) return 0; + data->disk = disk; + /* Read the superblock. */ - grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), - &data->sblock); + grub_nilfs2_load_sb (data); if (grub_errno) goto fail; - /* Make sure this is an nilfs2 filesystem. */ - if (!grub_nilfs2_valid_sb (&data->sblock)) - { - grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); - goto fail; - } - nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); /* Read the last segment summary. */ @@ -748,8 +795,6 @@ grub_nilfs2_mount (grub_disk_t disk) if (grub_errno) goto fail; - data->disk = disk; - grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); if (grub_errno) diff --git a/include/grub/disk.h b/include/grub/disk.h index e60b1f3de..e7f807e0e 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -138,6 +138,9 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; #define GRUB_DISK_CACHE_SIZE 8 #define GRUB_DISK_CACHE_BITS 3 +/* Return value of grub_disk_get_size() in case disk size is unknown. */ +#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL + /* This is called from the memory manager. */ void grub_disk_cache_invalidate_all (void); From b1d17e10e031a9d3dbbfb2e227509cf8137015bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 21:01:01 +0200 Subject: [PATCH 270/503] * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use GRUB_DISK_SIZE_UNKNOWN. * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. --- ChangeLog | 6 ++++++ disk/i386/pc/biosdisk.c | 3 ++- disk/ieee1275/ofdisk.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a35843554..c388ebd27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Vladimir Serbinenko + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use + GRUB_DISK_SIZE_UNKNOWN. + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. + 2010-05-31 Jiro SEKIBA * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index 94d0e3708..f82f91ff0 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -120,7 +120,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) { data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; data->sectors = 32; - total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */ + /* TODO: get the correct size. */ + total_sectors = GRUB_DISK_SIZE_UNKNOWN; } else if (drive & 0x80) { diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index e5a4a67fa..d0d9e894f 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -204,7 +204,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) /* 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; + disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; disk->id = (unsigned long) op; From 7d4873c26a80e0d05c0952aa45f4bda59e1e3f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Tue, 1 Jun 2010 02:10:19 +0200 Subject: [PATCH 271/503] =?UTF-8?q?Merge=20Ale=C5=A1'=20latest=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bus/usb/ohci.c | 156 ++++++++++++++++++++++++++++++---------- bus/usb/uhci.c | 19 +++-- bus/usb/usbtrans.c | 8 +++ disk/scsi.c | 33 ++++++++- disk/usbms.c | 40 ++++++++--- include/grub/usb.h | 3 +- include/grub/usbtrans.h | 3 + term/usb_keyboard.c | 1 - 8 files changed, 206 insertions(+), 57 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 03768d39e..ac6f61ee8 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -116,6 +116,11 @@ typedef enum #define GRUB_OHCI_PERIODIC_START 0x257f #define GRUB_OHCI_FRAME_INTERVAL 0x2edf +#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) +#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) +#define GRUB_OHCI_SET_PORT_RESET (1 << 4) +#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -281,7 +286,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, /* Misc. pre-sets. */ o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); @@ -396,8 +401,10 @@ grub_ohci_transaction (grub_ohci_td_t td, break; } +#if 0 /* Always generate interrupt */ /* Generate no interrupts. */ token |= 7 << 21; +#endif /* Set the token. */ token |= toggle << 24; @@ -444,9 +451,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint32_t status; grub_uint32_t control; grub_usb_err_t err; - int i, j; + int i; grub_uint64_t maxtime; int err_timeout = 0; + int err_unrec = 0; + grub_uint32_t intstatus; + grub_uint32_t tderr_addr = 0; /* Allocate an Endpoint Descriptor. */ ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); @@ -479,11 +489,13 @@ grub_ohci_transfer (grub_usb_controller_t dev, + (i + 1) * sizeof (td_list[0])); } +#if 0 /* Better will be enable interrupt on all TDs. */ /* The last-1 TD token we should change to enable interrupt when TD finishes. * As OHCI interrupts are disabled, it does only setting of WDH bit in * HcInterruptStatus register - and that is what we want to safely detect * normal end of all transactions. */ td_list[transfer->transcnt - 1].token &= ~(7 << 21); +#endif td_list[transfer->transcnt].token = 0; td_list[transfer->transcnt].buffer = 0; @@ -582,9 +594,11 @@ grub_ohci_transfer (grub_usb_controller_t dev, } grub_dprintf ("ohci", "wait for completion\n"); - grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n", + grub_dprintf ("ohci", + "begin: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); /* Safety measure to avoid a hang. */ maxtime = grub_get_time_ms () + 1000; @@ -592,30 +606,34 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Wait until the transfer is completed or STALLs. */ do { - grub_cpu_idle (); + /* Check transfer status */ + intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + if ((intstatus & 0x2) != 0) + { + grub_dprintf ("ohci", "Current HccaDoneHead=0x%08x\n", + o->hcca->donehead); + /* Remember last successful TD */ + tderr_addr = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + /* Reset DoneHead */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* if TD is last, finish */ + if (tderr_addr == td_list_addr + + sizeof (td_list[0]) * (transfer->transcnt - 1)) + break; + continue; + } + + if ((intstatus & 0x10) != 0) + { /* Unrecoverable error - only reset can help...! */ + err_unrec = 1; + break; + } /* Detected a HALT. */ if (grub_le_to_cpu32 (ed->td_head) & 1) break; - - if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x2) != 0) - { - if ((grub_le_to_cpu32 (o->hcca->donehead) & ~0xf) - == td_list_addr + (transfer->transcnt - 1) * sizeof (td_list[0])) - break; - /* Done Head can be updated on some another place if ED is halted. */ - if (grub_le_to_cpu32 (ed->td_head) & 1) - break; - - /* If there is not HALT in ED, it is not correct, so debug it, reset - * donehead and WDH and continue waiting. */ - grub_dprintf ("ohci", "Incorrect HccaDoneHead=0x%08x\n", - o->hcca->donehead); - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - continue; - } /* Timeout ? */ if (grub_get_time_ms () > maxtime) { @@ -628,9 +646,45 @@ grub_ohci_transfer (grub_usb_controller_t dev, if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) break; + + grub_cpu_idle (); } while (1); + grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); + + if (!tderr_addr) + { + /* It means that something wrong happened, + * it could be: + * - timeout and no TD processed + * - some or unrecoverable error and no TD processed + * - something unexpected... :-( */ + /* Try look into DONEHEAD reg., but there should be also zero */ + grub_dprintf("ohci", "HCCA DoneHead is zero, something is bad!\n"); + tderr_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf; + } + + /* Remember last processed transaction (TD) - it is necessary for + * proper setting of toggle bit in next transaction. */ + transfer->last_trans = (tderr_addr - td_list_addr) / sizeof (*td_list); + + /* Check correct value in last_trans */ + /* It could happen if timeout happens and no TD was retired */ + if (transfer->last_trans >= transfer->transcnt || !tderr_addr) + { + grub_dprintf("ohci", "tder==0 or out of TDs range!\n"); + grub_dprintf("ohci", "tderr_addr=0x%x, td_list=%p,\n\t\t last_trans=%d, transcnt=%d\n", + tderr_addr, td_list, transfer->last_trans, transfer->transcnt); + /* We should set something valid... */ + transfer->last_trans = -1; /* Probably no TD done */ + tderr_addr = td_list_addr; + } + + /* In case of timeout do not detect error from TD */ if (err_timeout) { err = GRUB_ERR_TIMEOUT; @@ -640,20 +694,25 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_le_to_cpu32(ed->td_tail), grub_le_to_cpu32(ed->next_ed)); } + /* In case of unrecoverable error do not detect error from TD */ + else if (err_unrec) + { + err = GRUB_USB_ERR_UNRECOVERABLE; + grub_dprintf("ohci", + "Unrecoverable error, target=%08x, head=%08x\n" + "\t\ttail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); + } else if (grub_le_to_cpu32 (ed->td_head) & 1) { - grub_uint32_t td_err_addr; grub_uint8_t errcode; grub_ohci_td_t tderr = NULL; - td_err_addr = (grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf); - if (td_err_addr == 0) - /* If DONEHEAD==0 it means that correct address is in HCCA. - * It should be always now! */ - td_err_addr = (grub_le_to_cpu32 (o->hcca->donehead) & ~0xf); - tderr = (grub_ohci_td_t) ((char *) td_list - + (td_err_addr - td_list_addr)); + + (tderr_addr - td_list_addr)); errcode = grub_le_to_cpu32 (tderr->token) >> 28; grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode); @@ -702,17 +761,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, case 8: /* XXX: Data overrun error. */ err = GRUB_USB_ERR_DATA; - j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); - grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", tderr, j); + grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", + tderr, transfer->last_trans); break; case 9: /* XXX: Data underrun error. */ err = GRUB_USB_ERR_DATA; + grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", + tderr, transfer->last_trans); grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n", 1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer)); - j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); - grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", tderr, j); break; case 10: @@ -764,7 +823,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); /* Wait for new SOF */ - while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + while (((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0) + && !err_unrec); /* Now it should be safe to change CONTROL and BULK lists. */ /* Important cleaning. */ @@ -774,7 +834,29 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - + + if (err_unrec) + { + /* Do OHCI reset in case of unrecoverable error - maybe we will need + * do more - re-enumerate bus etc. (?) */ + + /* Suspend the OHCI by issuing a reset. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ + grub_millisleep (1); + grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); + + /* Misc. resets. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + /* Enable the OHCI. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, (2 << 6)); + } + grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err); grub_dma_free (td_list_chunk); diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index eb533c926..1510f98e8 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -332,13 +332,20 @@ grub_free_td (struct grub_uhci *u, grub_uhci_td_t td) } static void -grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td) +grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td, + grub_usb_transfer_t transfer) { - /* Free the TDs in this queue. */ - while (td) + int i; /* Index of TD in transfer */ + + /* Free the TDs in this queue and set last_trans. */ + for (i=0; td; i++) { grub_uhci_td_t tdprev; + /* Check state of TD and possibly set last_trans */ + if (transfer && (td->linkptr & 1)) + transfer->last_trans = i; + /* Unlink the queue. */ tdprev = td; td = (grub_uhci_td_t) td->linkptr2; @@ -461,7 +468,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, td_prev->linkptr = 1; if (td_first) - grub_free_queue (u, td_first); + grub_free_queue (u, td_first, NULL); return GRUB_USB_ERR_INTERNAL; } @@ -560,7 +567,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, /* Place the QH back in the free list and deallocate the associated TDs. */ qh->elinkptr = 1; - grub_free_queue (u, td_first); + grub_free_queue (u, td_first, transfer); return err; } @@ -609,7 +616,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_uhci_writereg16 (u, reg, enable << 9); /* Wait for the reset to complete. XXX: How long exactly? */ - grub_millisleep (10); + grub_millisleep (50); /* For root hub should be nominaly 50ms */ status = grub_uhci_readreg16 (u, reg); grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); grub_dprintf ("uhci", "reset completed\n"); diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 0bf5ee6de..b3ee167a1 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -213,6 +213,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->max = max; transfer->dev = dev; + transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */ /* Allocate an array of transfer data structures. */ transfer->transactions = grub_malloc (transfer->transcnt @@ -240,6 +241,13 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, } err = dev->controller.dev->transfer (&dev->controller, transfer); + /* We must remember proper toggle value even if some transactions + * were not processed - correct value should be inversion of last + * processed transaction (TD). */ + if (transfer->last_trans >= 0) + toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1; + else + toggle = dev->toggle[endpoint]; /* Nothing done, take original */ grub_dprintf ("usb", "toggle=%d\n", toggle); dev->toggle[endpoint] = toggle; diff --git a/disk/scsi.c b/disk/scsi.c index e8bfb6a3f..dffabc26e 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -421,7 +421,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) /* According to USB MS tests specification, issue Test Unit Ready * until OK */ - maxtime = grub_get_time_ms () + 1000; + maxtime = grub_get_time_ms () + 5000; /* It is safer value */ do { /* Timeout is necessary - for example in case when we have @@ -519,6 +519,37 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, /* XXX: Never reached. */ return GRUB_ERR_NONE; + +#if 0 /* Workaround - it works - but very slowly, from some reason + * unknown to me (specially on OHCI). Do not use it. */ + /* Split transfer requests to device sector size because */ + /* some devices are not able to transfer more than 512-1024 bytes */ + grub_err_t err = GRUB_ERR_NONE; + + for ( ; size; size--) + { + /* Depending on the type, select a read function. */ + switch (scsi->devtype) + { + case grub_scsi_devtype_direct: + err = grub_scsi_read10 (disk, sector, 1, buf); + break; + + case grub_scsi_devtype_cdrom: + err = grub_scsi_read12 (disk, sector, 1, buf); + break; + + default: /* This should not happen */ + return GRUB_ERR_READ_ERROR; + } + if (err) + return err; + sector++; + buf += scsi->blocksize; + } + + return err; +#endif } static grub_err_t diff --git a/disk/usbms.c b/disk/usbms.c index 7b719fb84..a49b30e7e 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -253,6 +253,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, struct grub_usbms_csw status; static grub_uint32_t tag = 0; grub_usb_err_t err = GRUB_USB_ERR_NONE; + grub_usb_err_t errCSW = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; grub_size_t i; @@ -290,9 +291,8 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, { if (err == GRUB_USB_ERR_STALL) { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto retry; + goto CheckCSW; } return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed"); } @@ -302,7 +302,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, { err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); - if (err) goto CheckCSW; + if (err) + { + if (err == GRUB_USB_ERR_STALL) + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + goto CheckCSW; + } /* Debug print of received data. */ grub_dprintf ("usb", "buf:\n"); if (size <= 64) @@ -316,6 +321,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf); grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); grub_dprintf ("usb", "buf:\n"); + if (err) + { + if (err == GRUB_USB_ERR_STALL) + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); + goto CheckCSW; + } /* Debug print of sent data. */ if (size <= 256) for (i=0; idev, dev->in->endp_addr, + errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, sizeof (status), (char *) &status); - if (err) + if (errCSW) { grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, sizeof (status), (char *) &status); - if (err) + if (errCSW) { /* Bulk-only reset device. */ + grub_dprintf ("usb", "Bulk-only reset device - errCSW\n"); 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); @@ -347,9 +359,11 @@ CheckCSW: status.signature, status.tag, status.residue); grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status); - /* If phase error, do bulk-only reset device. */ - if (status.status == 2) - { + /* If phase error or not valid signature, do bulk-only reset device. */ + if ((status.status == 2) || + (status.signature != grub_cpu_to_le32(0x53425355))) + { /* Bulk-only reset device. */ + grub_dprintf ("usb", "Bulk-only reset device - bad status\n"); 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); @@ -357,9 +371,13 @@ CheckCSW: goto retry; } - if (status.status) + /* If "command failed" status or data transfer failed -> error */ + if ((status.status || err) && !read_write) return grub_error (GRUB_ERR_READ_ERROR, "error communication with USB Mass Storage device"); + else if ((status.status || err) && read_write) + return grub_error (GRUB_ERR_WRITE_ERROR, + "error communication with USB Mass Storage device"); return GRUB_ERR_NONE; } diff --git a/include/grub/usb.h b/include/grub/usb.h index cbbc39303..64dc78d61 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -35,7 +35,8 @@ typedef enum GRUB_USB_ERR_NAK, GRUB_USB_ERR_BABBLE, GRUB_USB_ERR_TIMEOUT, - GRUB_USB_ERR_BITSTUFF + GRUB_USB_ERR_BITSTUFF, + GRUB_USB_ERR_UNRECOVERABLE } grub_usb_err_t; typedef enum diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index cd818e1fc..40fc0dd5f 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -58,6 +58,9 @@ struct grub_usb_transfer struct grub_usb_device *dev; struct grub_usb_transaction *transactions; + + int last_trans; + /* Index of last processed transaction in OHCI/UHCI driver. */ }; typedef struct grub_usb_transfer *grub_usb_transfer_t; diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 5d76c5e02..69d5709b6 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include From 0d9ff59345a63087e02bb2415a62ae6cd50a6f42 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 1 Jun 2010 18:05:29 +0100 Subject: [PATCH 272/503] * kern/emu/getroot.c (find_root_device_from_mountinfo): Use getline instead of fgets into a static buffer. Use sizeof instead of strlen on a constant string. Thanks to Vladimir for review. --- ChangeLog.btrfs-probe | 2 +- kern/emu/getroot.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog.btrfs-probe b/ChangeLog.btrfs-probe index 77c9995c8..c79e6b6a4 100644 --- a/ChangeLog.btrfs-probe +++ b/ChangeLog.btrfs-probe @@ -1,4 +1,4 @@ -2010-05-18 Colin Watson +2010-06-01 Colin Watson Add btrfs probing support, currently only in the single-device case. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index da62089fa..97c24115b 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -93,14 +93,15 @@ static char * find_root_device_from_mountinfo (const char *dir) { FILE *fp; - char buf[1024]; /* XXX */ + char *buf = NULL; + size_t len = 0; char *ret = NULL; fp = fopen ("/proc/self/mountinfo", "r"); if (! fp) return NULL; /* fall through to other methods */ - while (fgets (buf, sizeof (buf), fp)) + while (getline (&buf, &len, fp) > 0) { int mnt_id, parent_mnt_id; unsigned int major, minor; @@ -139,7 +140,7 @@ find_root_device_from_mountinfo (const char *dir) if (!sep) continue; - sep += strlen (" - "); + sep += sizeof (" - ") - 1; if (sscanf (sep, "%s %s", fstype, device) != 2) continue; @@ -152,6 +153,7 @@ find_root_device_from_mountinfo (const char *dir) ret = strdup (device); } + free (buf); fclose (fp); return ret; } From 3b97788878888b16960c3723d86875a01abc3f2f Mon Sep 17 00:00:00 2001 From: Peter Henn Date: Tue, 1 Jun 2010 18:40:03 +0100 Subject: [PATCH 273/503] * disk/mdraid_linux.c (grub_mdraid_detect): Fix calculation of 1.x chunk size and disk size, which are already given as sector counts as distinct from the 0.90 units. Fetch the correct device number from the role table instead of using the table index. --- ChangeLog.raid | 7 +++++++ disk/mdraid_linux.c | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog.raid b/ChangeLog.raid index 854702f41..989f0bc09 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,10 @@ +2009-12-15 Peter Henn + + * disk/mdraid_linux.c (grub_mdraid_detect): Fix calculation of 1.x + chunk size and disk size, which are already given as sector counts + as distinct from the 0.90 units. Fetch the correct device number + from the role table instead of using the table index. + 2009-11-16 Felix Zielcke * disk/mdraid_linux.c (grub_mdraid_detect): Remove a wrong call diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index d29803719..08e10ab45 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -371,9 +371,12 @@ superblock_0_90: array->level = grub_le_to_cpu32 (sb_1x->level); array->layout = grub_le_to_cpu32 (sb_1x->layout); array->total_devs = grub_le_to_cpu32 (sb_1x->raid_disks); - array->disk_size = grub_le_to_cpu64 (sb_1x->size) * 2; + array->disk_size = grub_le_to_cpu64 (sb_1x->size); array->chunk_size = grub_le_to_cpu32 (sb_1x->chunksize); - array->index = grub_le_to_cpu32 (sb_1x->dev_number); + if (grub_le_to_cpu32 (sb_1x->dev_number) < grub_le_to_cpu32 (sb_1x->max_dev)) + array->index = grub_le_to_cpu16 (sb_1x->dev_roles[grub_le_to_cpu32 (sb_1x->dev_number)]); + else + array->index = 0xffff; /* disk will be later not used! */ array->uuid_len = 16; array->uuid = grub_malloc (16); if (!array->uuid) From e726afa89d8fabd1c962655b7a1e2d0bdbaa0e3d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 1 Jun 2010 18:40:45 +0100 Subject: [PATCH 274/503] fix indentation --- disk/raid.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/disk/raid.c b/disk/raid.c index 07ae606b9..d6a1f1d48 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -562,16 +562,16 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, Use it directly as GRUB device. */ if (! array->name) { - array->name = grub_malloc (13); - if (! array->name) - { - grub_free (array->uuid); - grub_free (array); + 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); - } + return grub_errno; + } + grub_sprintf (array->name, "md%d", array->number); + } else grub_sprintf (array->name, "%s", array->name); From 390b0676c482abcc47c70a530b2bf4edb10f7479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Wed, 2 Jun 2010 02:04:45 +0200 Subject: [PATCH 275/503] Use dev->descdev.maxsize0 even if dev->initialized isn't set --- bus/usb/usbtrans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index b3ee167a1..e1b9097e6 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -76,7 +76,7 @@ grub_usb_control_msg (grub_usb_device_t dev, setupdata_addr = grub_dma_get_phys (setupdata_chunk); /* Determine the maximum packet size. */ - if (dev->initialized && dev->descdev.maxsize0) + if (dev->descdev.maxsize0) max = dev->descdev.maxsize0; else max = 64; From ab6316112cc0ea4149168972c47f75b57a7b9eeb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 01:23:34 +0100 Subject: [PATCH 276/503] * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes. --- ChangeLog | 5 +++++ conf/any-emu.rmk | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index de0b62f08..d88c510eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include + kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes. + 2010-06-01 Colin Watson Add btrfs probing support, currently only in the single-device case. diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 000996172..21e139a32 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -20,14 +20,14 @@ TARGET_NO_STRIP = yes ifneq ($(TARGET_NO_MODULES), yes) kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c +else +kernel_img_SOURCES += grub_emu_init.c +endif ifneq ($(target_cpu), i386) ifneq ($(target_cpu), x86_64) kernel_img_SOURCES += kern/$(target_cpu)/cache.S endif endif -else -kernel_img_SOURCES += grub_emu_init.c -endif # For halt.mod. pkglib_MODULES += halt.mod From 9121567e16cf77ccd1f4a148580718436101c247 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 02:37:55 +0100 Subject: [PATCH 277/503] * commands/gptsync.c (grub_cmd_gptsync): Fix typos. (GRUB_MOD_INIT): Fix capitalisation. * docs/grub.texi (Command-line and menu entry commands): Document gettext and gptsync commands. --- ChangeLog | 7 +++++++ commands/gptsync.c | 8 ++++---- docs/grub.texi | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d88c510eb..9c11b2fa9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-02 Colin Watson + + * commands/gptsync.c (grub_cmd_gptsync): Fix typos. + (GRUB_MOD_INIT): Fix capitalisation. + * docs/grub.texi (Command-line and menu entry commands): Document + gettext and gptsync commands. + 2010-06-02 Colin Watson * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include diff --git a/commands/gptsync.c b/commands/gptsync.c index d217b5d5c..6364c13f7 100644 --- a/commands/gptsync.c +++ b/commands/gptsync.c @@ -138,8 +138,8 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), { grub_device_close (dev); return grub_error (GRUB_ERR_OUT_OF_RANGE, - "only partitions resding in the first 2TB " - "can be presen in hybrid MBR"); + "only partitions residing in the first 2TB " + "can be present in hybrid MBR"); } @@ -243,8 +243,8 @@ GRUB_MOD_INIT(gptsync) cmd = grub_register_command ("gptsync", grub_cmd_gptsync, N_("DEVICE [PARTITION[+/-[TYPE]]] ..."), N_("Fill hybrid MBR of GPT drive DEVICE. " - "specified partitions will be a part " - "of hybrid mbr. Up to 3 partitions are " + "Specified partitions will be a part " + "of hybrid MBR. Up to 3 partitions are " "allowed. TYPE is an MBR type. " "+ means that partition is active. " "Only one partition can be active.")); diff --git a/docs/grub.texi b/docs/grub.texi index bcc05c1f8..52aca3fbd 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1139,6 +1139,8 @@ you forget a command, you can run the command @command{help} * date:: Display or set current date and time * echo:: Display a line of text * export:: Export an environment variable +* gettext:: Translate a string +* gptsync:: Fill an MBR based on GPT entries * halt:: Shut down your computer * help:: Show help messages * insmod:: Insert a module @@ -1320,6 +1322,38 @@ to subsidiary configuration files loaded using @command{configfile}. @end deffn +@node gettext +@subsection gettext + +@deffn Command gettext string +Translate @var{string} into the current language. + +The current language code is stored in the @samp{lang} variable in GRUB's +environment. Translation files in MO format are read from +@samp{locale_dir}, usually @file{/boot/grub/locale}. +@end deffn + + +@node gptsync +@subsection gptsync + +@deffn Command gptsync device [partition[+/-[type]]] @dots{} +Disks using the GUID Partition Table (GPT) also have a legacy Master Boot +Record (MBR) partition table for compatibility with the BIOS and with older +operating systems. The legacy MBR can only represent a limited subset of +GPT partition entries. + +This command populates the legacy MBR with the specified @var{partition} +entries on @var{device}. Up to three partitions may be used. + +@var{type} is an MBR partition type code; prefix with @samp{0x} if you want +to enter this in hexadecimal. The separator between @var{partition} and +@var{type} may be @samp{+} to make the partition active, or @samp{-} to make +it inactive; only one partition may be active. If both the separator and +type are omitted, then the partition will be inactive. +@end deffn + + @node halt @subsection halt From 34c9f0e949cfadddd88a8229f4d10184f3263646 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 02:50:04 +0100 Subject: [PATCH 278/503] * docs/grub.texi (direntry): Remove grub-terminfo reference. (GNU GRUB manual): Likewise. (General commands): Update description of `terminfo' for GRUB 2. --- ChangeLog | 6 ++++++ docs/grub.texi | 21 +++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c11b2fa9..8a6f98be1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (direntry): Remove grub-terminfo reference. + (GNU GRUB manual): Likewise. + (General commands): Update description of `terminfo' for GRUB 2. + 2010-06-02 Colin Watson * commands/gptsync.c (grub_cmd_gptsync): Fix typos. diff --git a/docs/grub.texi b/docs/grub.texi index 52aca3fbd..657a5d146 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -34,9 +34,6 @@ Invariant Sections. @direntry * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive -* grub-terminfo: (grub)Invoking grub-terminfo. Generate a terminfo - command from a - terminfo name @end direntry @setchapternewpage odd @@ -89,7 +86,6 @@ This edition documents version @value{VERSION}. * 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-terminfo:: How to generate a terminfo command * 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 @@ -1076,7 +1072,7 @@ Commands usable anywhere in the menu and in the command-line. @menu * serial:: Set up a serial device -* terminfo:: Define escape sequences for a terminal +* terminfo:: Define terminal type @end menu @@ -1108,15 +1104,16 @@ support. See also @ref{Serial terminal}. @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. +@deffn Command terminfo [term] +Define the capabilities of your terminal by giving the name of an entry in +the terminfo database, which should correspond roughly to a @samp{TERM} +environment variable in Unix. -You can use the utility @command{grub-terminfo} to generate -appropriate arguments to this command. @xref{Invoking grub-terminfo}. +At the moment, only @samp{vt100} is supported in GRUB 2. If you need other +terminal types, please contact us to discuss the best way to include support +for these in GRUB. -If no option is specified, the current settings are printed. +If no option is specified, the current terminal type is printed. @end deffn From a18c78347304d00b521556ccc76d4c8564d417b0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:51:35 +0200 Subject: [PATCH 279/503] Fewstylistic fixes --- bus/usb/ohci.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index ac6f61ee8..de0a4e7ac 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -594,10 +594,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, } grub_dprintf ("ohci", "wait for completion\n"); - grub_dprintf ("ohci", - "begin: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_dprintf ("ohci", "begin: control=0x%02x status=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_dprintf ("ohci","intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); /* Safety measure to avoid a hang. */ @@ -621,7 +621,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (tderr_addr == td_list_addr + sizeof (td_list[0]) * (transfer->transcnt - 1)) break; - continue; + continue; } if ((intstatus & 0x10) != 0) @@ -651,9 +651,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, } while (1); - grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_dprintf ("ohci", "intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); if (!tderr_addr) @@ -688,21 +689,22 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (err_timeout) { err = GRUB_ERR_TIMEOUT; - grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n\t\ttail=%08x, next=%08x\n", - grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head), - grub_le_to_cpu32(ed->td_tail), - grub_le_to_cpu32(ed->next_ed)); + grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head)); + grub_dprintf("ohci", "tail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); } /* In case of unrecoverable error do not detect error from TD */ else if (err_unrec) { err = GRUB_USB_ERR_UNRECOVERABLE; grub_dprintf("ohci", - "Unrecoverable error, target=%08x, head=%08x\n" - "\t\ttail=%08x, next=%08x\n", + "Unrecoverable error, target=%08x, head=%08x\n", grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_head)); + grub_dprintf("ohci", "tail=%08x, next=%08x\n", grub_le_to_cpu32(ed->td_tail), grub_le_to_cpu32(ed->next_ed)); } From 2325800310ce4ac9a5088f5c3fca68e44155e145 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:52:35 +0200 Subject: [PATCH 280/503] Fix last_trans determination --- bus/usb/ohci.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index de0a4e7ac..4d66df0bc 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -671,15 +671,21 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Remember last processed transaction (TD) - it is necessary for * proper setting of toggle bit in next transaction. */ - transfer->last_trans = (tderr_addr - td_list_addr) / sizeof (*td_list); - + transfer->last_trans = ((tderr_addr - td_list_addr) / sizeof (*td_list)); + grub_dprintf("ohci", "tderr_addr=0x%x, td_list_addr=0x%x,\n", + tderr_addr, td_list_addr); + + if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) + transfer->last_trans = transfer->transcnt - 1; + /* Check correct value in last_trans */ /* It could happen if timeout happens and no TD was retired */ if (transfer->last_trans >= transfer->transcnt || !tderr_addr) { - grub_dprintf("ohci", "tder==0 or out of TDs range!\n"); - grub_dprintf("ohci", "tderr_addr=0x%x, td_list=%p,\n\t\t last_trans=%d, transcnt=%d\n", - tderr_addr, td_list, transfer->last_trans, transfer->transcnt); + grub_dprintf("ohci", "tderr==0 or out of TDs range!\n"); + grub_dprintf("ohci", "last_trans=%d, transcnt=%d\n", + transfer->last_trans, transfer->transcnt); + /* We should set something valid... */ transfer->last_trans = -1; /* Probably no TD done */ tderr_addr = td_list_addr; @@ -713,6 +719,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint8_t errcode; grub_ohci_td_t tderr = NULL; + transfer->last_trans--; + tderr = (grub_ohci_td_t) ((char *) td_list + (tderr_addr - td_list_addr)); From f1cb760c99f77795f1c91f11f8157d6984f4593f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:52:52 +0200 Subject: [PATCH 281/503] Disable unused list --- bus/usb/ohci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 4d66df0bc..fd378cc8d 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -563,9 +563,14 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); +#define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5) +#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) + /* Enable the Bulk list. */ control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - control |= 1 << 5; + control |= GRUB_OHCI_REG_CONTROL_BULK_ENABLE; + control &= ~GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set BulkListFilled. */ @@ -578,12 +583,15 @@ grub_ohci_transfer (grub_usb_controller_t dev, case GRUB_USB_TRANSACTION_TYPE_CONTROL: { + grub_dprintf ("ohci", "add to control list\n"); + /* Set ControlList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); /* Enable the Control list. */ - control |= 1 << 4; + control |= GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; + control &= ~GRUB_OHCI_REG_CONTROL_BULK_ENABLE; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set ControlListFilled. */ From d4955444976a90377d0ff9d8140bb906c2c36f46 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 05:00:54 +0200 Subject: [PATCH 282/503] Shut down PHCI controller harder --- bus/usb/ohci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index fd378cc8d..a42d9fee1 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -970,7 +970,10 @@ grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); } + grub_millisleep (10); return GRUB_ERR_NONE; } From 288dd6ed3d88420e4fcc28a7aeeef0916c673cd5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 11:14:02 +0100 Subject: [PATCH 283/503] * docs/grub.texi (Configuration): New section, documenting configuration file generation using grub-mkconfig. I've left a slot for documenting the full shell scripting format but have not yet started on writing that up. (Invoking grub-mkconfig): New section. --- ChangeLog | 8 ++ docs/grub.texi | 221 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 228 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8a6f98be1..214be173c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Configuration): New section, documenting + configuration file generation using grub-mkconfig. I've left a slot + for documenting the full shell scripting format but have not yet + started on writing that up. + (Invoking grub-mkconfig): New section. + 2010-06-02 Colin Watson * docs/grub.texi (direntry): Remove grub-terminfo reference. diff --git a/docs/grub.texi b/docs/grub.texi index 657a5d146..77f151cfc 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -20,7 +20,7 @@ This manual is for GNU GRUB (version @value{VERSION}, @value{UPDATED}). -Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009 Free Software Foundation, Inc. +Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -34,6 +34,7 @@ Invariant Sections. @direntry * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive +* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration @end direntry @setchapternewpage odd @@ -86,6 +87,7 @@ This edition documents version @value{VERSION}. * 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-mkconfig:: Generate a GRUB configuration file * 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 @@ -694,6 +696,197 @@ the size, run the command @command{uppermem} @emph{before} loading the kernel. @xref{uppermem}, for more information. +@node Configuration +@chapter Writing your own configuration file + +GRUB is configured using @file{grub.cfg}, usually located under +@file{/boot/grub}. This file is quite flexible, but most users will not +need to write the whole thing by hand. + +@menu +* Simple configuration:: Recommended for most users +* Shell-like scripting:: For power users and developers +@end menu + + +@node Simple configuration +@section Simple configuration handling + +The program @command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}) +generates @file{grub.cfg} files suitable for most cases. It is suitable for +use when upgrading a distribution, and will discover available kernels and +attempt to generate menu entries for them. + +The file @file{/etc/default/grub} controls the operation of +@command{grub-mkconfig}. It is sourced by a shell script, and so must be +valid POSIX shell input; normally, it will just be a sequence of +@samp{KEY=value} lines, but if the value contains spaces or other special +characters then it must be quoted. For example: + +@example +GRUB_TERMINAL_INPUT="console serial" +@end example + +Valid keys in @file{/etc/default/grub} are as follows: + +@table @samp +@item GRUB_DEFAULT +The default menu entry. This may be a number, in which case it identifies +the Nth entry in the generated menu counted from zero, or the full name of a +menu entry, or the special string @samp{saved}. Using the full name may be +useful if you want to set a menu entry as the default even though there may +be a variable number of entries before it. + +If you set this to @samp{saved}, then the default menu entry will be that +saved by @samp{GRUB_SAVEDEFAULT}, @command{grub-set-default}, or +@command{grub-reboot}. + +The default is @samp{0}. + +@item GRUB_SAVEDEFAULT +If this option is set to @samp{true}, then, when an entry is selected, save +it as a new default entry for use by future runs of GRUB. This is only +useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because +@samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with +@command{grub-set-default} or @command{grub-reboot}. Unset by default. + +@item GRUB_TIMEOUT +Boot the default entry this many seconds after the menu is displayed, unless +a key is pressed. The default is @samp{5}. Set to @samp{0} to boot +immediately without displaying the menu, or to @samp{-1} to wait +indefinitely. + +@item GRUB_HIDDEN_TIMEOUT +Wait this many seconds for a key to be pressed before displaying the menu. +If no key is pressed during that time, boot immediately. Unset by default. + +@item GRUB_HIDDEN_TIMEOUT_QUIET +In conjunction with @samp{GRUB_HIDDEN_TIMEOUT}, set this to @samp{true} to +suppress the verbose countdown while waiting for a key to be pressed before +displaying the menu. Unset by default. + +@item GRUB_DEFAULT_BUTTON +@itemx GRUB_TIMEOUT_BUTTON +@itemx GRUB_HIDDEN_TIMEOUT_BUTTON +@itemx GRUB_BUTTON_CMOS_ADDRESS +Variants of the corresponding variables without the @samp{_BUTTON} suffix, +used to support vendor-specific power buttons. @xref{Vendor power-on keys}. + +@item GRUB_DISTRIBUTOR +Set by distributors of GRUB to their identifying name. This is used to +generate more informative menu entry titles. + +@item GRUB_TERMINAL_INPUT +Select the terminal input device. You may select multiple devices here, +separated by spaces. + +Valid terminal input names depend on the platform, but may include +@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal), +@samp{ofconsole} (Open Firmware console), @samp{at_keyboard} (PC AT +keyboard, mainly useful with Coreboot), or @samp{usb_keyboard} (USB keyboard +using the HID Boot Protocol, for cases where the firmware does not handle +this). + +The default is to use the platform's native terminal input. + +@item GRUB_TERMINAL_OUTPUT +Select the terminal output device. You may select multiple devices here, +separated by spaces. + +Valid terminal output names depend on the platform, but may include +@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal), +@samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware +console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot). + +The default is to use the platform's native terminal input. + +@item GRUB_TERMINAL +If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and +@samp{GRUB_TERMINAL_OUTPUT} to the same value. + +@item GRUB_SERIAL_COMMAND +A command to configure the serial port when using the serial console. +@xref{serial}. Defaults to @samp{serial}. + +@item GRUB_CMDLINE_LINUX +Command-line arguments to add to menu entries for the Linux kernel. + +@item GRUB_CMDLINE_LINUX_DEFAULT +Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set, two menu entries will be +generated for each Linux kernel: one default entry and one entry for +recovery mode. This option lists command-line arguments to add only to the +default menu entry, after those listed in @samp{GRUB_CMDLINE_LINUX}. + +@item GRUB_CMDLINE_NETBSD +@itemx GRUB_CMDLINE_NETBSD_DEFAULT +As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for +NetBSD. + +@item GRUB_DISABLE_LINUX_UUID +Normally, @command{grub-mkconfig} will generate menu entries that use +universally-unique identifiers (UUIDs) to identify the root filesystem to +the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is +usually more reliable, but in some cases it may not be appropriate. To +disable the use of UUIDs, set this option to @samp{true}. + +@item GRUB_DISABLE_LINUX_RECOVERY +Disable the generation of recovery mode menu entries for Linux. + +@item GRUB_DISABLE_NETBSD_RECOVERY +Disable the generation of recovery mode menu entries for NetBSD. + +@item GRUB_GFXMODE +Set the resolution used on the @samp{gfxterm} graphical terminal. Note that +you can only use modes which your graphics card supports via VESA BIOS +Extensions (VBE), so for example native LCD panel resolutions may not be +available. The default is @samp{640x480}. + +@item GRUB_BACKGROUND +Set a background image for use with the @samp{gfxterm} graphical terminal. +The value of this option must be a file readable by GRUB at boot time, and +it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}. +The image will be scaled if necessary to fit the screen. + +@item GRUB_THEME +Set a theme for use with the @samp{gfxterm} graphical terminal. +@xref{Themes}. + +@item GRUB_GFXPAYLOAD_LINUX +Set to @samp{text} to force the Linux kernel to boot in normal text mode, +@samp{keep} to preserve the graphics mode set using @samp{GRUB_GFXMODE}, +@samp{@var{width}x@var{height}}[@samp{x@var{depth}}] to set a particular +graphics mode, or a sequence of these separated by commas or semicolons to +try several modes in sequence. + +Depending on your kernel, your distribution, your graphics card, and the +phase of the moon, note that using this option may cause GNU/Linux to suffer +from various display problems, particularly during the early part of the +boot sequence. If you have problems, simply unset this option and GRUB will +tell Linux to boot in normal text mode. + +@item GRUB_DISABLE_OS_PROBER +Normally, @command{grub-mkconfig} will try to use the external +@command{os-prober} program, if installed, to discover other operating +systems installed on the same system and generate appropriate menu entries +for them. Set this option to @samp{true} to disable this. + +@item GRUB_INIT_TUNE +Play a tune on the speaker when GRUB starts. This is particularly useful +for users unable to see the screen. The value of this option is passed +directly to @ref{play}. +@end table + +For more detailed customisation of @command{grub-mkconfig}'s output, you may +edit the scripts in @file{/etc/grub.d} directly. +@file{/etc/grub.d/40_custom} is particularly useful for adding entire custom +menu entries; simply type the menu entries you want to add at the end of +that file, making sure to leave at least the first two lines intact. + + +@node Shell-like scripting +@section Writing full configuration files directly + + @node Serial terminal @chapter Using GRUB via a serial line @@ -1499,6 +1692,32 @@ into/from your computer. @end table +@node Invoking grub-mkconfig +@chapter Invoking grub-mkconfig + +The program @command{grub-mkconfig} generates a configuration file for GRUB +(@pxref{Simple configuration}). + +@example +grub-mkconfig -o /boot/grub/grub.cfg +@end example + +@command{grub-mkconfig} 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 -o @var{file} +@itemx --output=@var{file} +Send the generated configuration file to @var{file}. The default is to send +it to standard output. +@end table + + @node Obtaining and Building GRUB @appendix How to obtain and build GRUB From bb8ea0f5c324043bd09e024b41a2af262909b659 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 11:26:28 +0100 Subject: [PATCH 284/503] * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking the grub shell'. (Installation): Add reference to `Making a GRUB bootable CD-ROM'. (Installing GRUB using grub-install): Remove reference to the grub shell; mention `grub-mkimage' and `grub-setup' instead. (Invoking grub-install): Likewise. (Interface): Add reference to `Menu entry editor'. (serial): Remove `--device' option. --- ChangeLog | 11 +++++++++++ docs/grub.texi | 26 ++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 214be173c..905e36edf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking + the grub shell'. + (Installation): Add reference to `Making a GRUB bootable CD-ROM'. + (Installing GRUB using grub-install): Remove reference to the grub + shell; mention `grub-mkimage' and `grub-setup' instead. + (Invoking grub-install): Likewise. + (Interface): Add reference to `Menu entry editor'. + (serial): Remove `--device' option. + 2010-06-02 Colin Watson * docs/grub.texi (Configuration): New section, documenting diff --git a/docs/grub.texi b/docs/grub.texi index 77f151cfc..4c903729b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -85,7 +85,6 @@ This edition documents version @value{VERSION}. * 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-mkconfig:: Generate a GRUB configuration file * Obtaining and Building GRUB:: How to obtain and build GRUB @@ -451,6 +450,7 @@ the @dfn{boot directory}. @menu * Installing GRUB using grub-install:: +* Making a GRUB bootable CD-ROM:: @end menu @@ -530,11 +530,11 @@ 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. +real task is done by @command{grub-mkimage} and @command{grub-setup}. +Therefore, you may run those commands 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 @@ -1073,6 +1073,7 @@ 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 @end menu @@ -1272,7 +1273,7 @@ Commands usable anywhere in the menu and in the command-line. @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}] +@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] 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 @@ -1281,10 +1282,7 @@ is to be found; if specified it takes precedence over @var{unit}. @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}). +@samp{even} and defaults to @samp{no}. The serial port is not used as a communication channel unless the @command{terminal} command is used (@pxref{terminal}). @@ -1654,9 +1652,9 @@ Unset the environment variable @var{envvar}. @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: +The program @command{grub-install} installs GRUB on your drive using +@command{grub-mkimage} and (on some platforms) @command{grub-setup}. You +must specify the device name on which you want to install GRUB, like this: @example grub-install @var{install_device} From 1c41aa7883f3f8ba94e7e0c447f434840a4a0161 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 12:47:11 +0100 Subject: [PATCH 285/503] * docs/grub.texi (Chain-loading): New section. (DOS/Windows): New section, borrowed from GRUB Legacy with details adjusted for GRUB 2. (SCO UnixWare): Likewise. (QNX): Likewise. (chainloader): Add reference to `Block list syntax'. (drivemap): New section. (parttool): New section. --- ChangeLog | 11 +++ docs/grub.texi | 187 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 193 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 905e36edf..b0fc06848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Chain-loading): New section. + (DOS/Windows): New section, borrowed from GRUB Legacy with details + adjusted for GRUB 2. + (SCO UnixWare): Likewise. + (QNX): Likewise. + (chainloader): Add reference to `Block list syntax'. + (drivemap): New section. + (parttool): New section. + 2010-06-02 Colin Watson * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking diff --git a/docs/grub.texi b/docs/grub.texi index 4c903729b..5f2e5e36a 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -647,6 +647,35 @@ use more complicated instructions. @xref{DOS/Windows}, for more information. +@node Chain-loading +@subsection Chain-loading an OS + +Operating systems that do not support Multiboot and do not have specific +support in GRUB (specific support is available for Linux, FreeBSD, NetBSD +and OpenBSD) must be chain-loaded, which involves loading another boot +loader and jumping to it in real mode. + +The @command{chainloader} command (@pxref{chainloader}) is used to set this +up. It is normally also necessary to load some GRUB modules and set the +appropriate root device. Putting this together, we get something like this, +for a Windows system on the first partition of the first hard disk: + +@verbatim +menuentry "Windows" { + insmod chain + insmod ntfs + set root=(hd0,1) + chainloader +1 +} +@end verbatim +@c FIXME: document UUIDs. + +On systems with multiple hard disks, an additional workaround may be +required. @xref{DOS/Windows}. + +Chain-loading is only supported on PC BIOS and EFI platforms. + + @node OS-specific notes @section Some caveats on OS-specific issues @@ -655,6 +684,9 @@ Here, we describe some caveats on several operating systems. @menu * GNU/Hurd:: * GNU/Linux:: +* DOS/Windows:: +* SCO UnixWare:: +* QNX:: @end menu @@ -696,6 +728,87 @@ the size, run the command @command{uppermem} @emph{before} loading the kernel. @xref{uppermem}, for more information. +@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{drivemap} (@pxref{drivemap}), like this: + +@example +drivemap -s (hd0) (hd1) +@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{hides} a DOS (or Windows) partition (@pxref{parttool}), DOS (or +Windows) will ignore the partition. If GRUB @dfn{unhides} a DOS (or Windows) +partition, 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 +parttool (hd0,1) hidden- +parttool (hd0,2) hidden+ +set root=(hd0,1) +chainloader +1 +parttool @verb{'${root}'} boot+ +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 +set root=(hd1,1) +chainloader --force +1 +parttool @verb{'${root}'} boot+ +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 +set root=(hd1,2) +chainloader +4 +boot +@end group +@end example + + @node Configuration @chapter Writing your own configuration file @@ -1325,6 +1438,7 @@ you forget a command, you can run the command @command{help} * configfile:: Load a configuration file * crc:: Calculate CRC32 checksums * date:: Display or set current date and time +* drivemap:: Map a drive to another * echo:: Display a line of text * export:: Export an environment variable * gettext:: Translate a string @@ -1334,6 +1448,7 @@ you forget a command, you can run the command @command{help} * insmod:: Insert a module * keystatus:: Check key modifier status * ls:: List devices or files +* parttool:: Modify partition table entries * play:: Play a tune * reboot:: Reboot your computer * set:: Set an environment variable @@ -1399,11 +1514,12 @@ grub> @kbd{cat /etc/fstab} @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}). +filesystem code, it can use the blocklist notation (@pxref{Block list +syntax}) 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 @@ -1458,6 +1574,32 @@ hour, minute, and second unchanged. @end deffn +@node drivemap +@subsection drivemap + +@deffn Command drivemap @option{-l}|@option{-r}|[@option{-s}] @ + from_drive to_drive +Without options, 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. For convenience, any partition +suffix on the drive is ignored, so you can safely use @verb{'${root}'} as a +drive specification. + +With the @option{-s} option, perform the reverse mapping as well, swapping +the two drives. + +With the @option{-l} option, list the current mappings. + +With the @option{-r} option, reset all mappings to the default values. + +For example: + +@example +drivemap -s (hd0) (hd1) +@end example +@end deffn + + @node echo @subsection echo @@ -1605,6 +1747,41 @@ name syntax}), then list the contents of that directory. @end deffn +@node parttool +@subsection parttool + +@deffn Command parttool partition commands +Make various modifications to partition table entries. + +Each @var{command} is either a boolean option, in which case it must be +followed with @samp{+} or @samp{-} (with no intervening space) to enable or +disable that option, or else it takes a value in the form +@samp{@var{command}=@var{value}}. + +Currently, @command{parttool} is only useful on DOS partition tables (also +known as Master Boot Record, or MBR). On these partition tables, the +following commands are available: + +@table @asis +@item @samp{boot} (boolean) +When enabled, this makes the selected partition be the active (bootable) +partition on its disk, clearing the active flag on all other partitions. +This command is limited to @emph{primary} partitions. + +@item @samp{type} (value) +Change the type of an existing partition. The value must be a number in the +range 0-0xFF (prefix with @samp{0x} to enter it in hexadecimal). + +@item @samp{hidden} (boolean) +When enabled, this hides the selected partition by setting the @dfn{hidden} +bit in its partition type code; when disabled, unhides the selected +partition by clearing this bit. This is useful only when booting DOS or +Wwindows and multiple primary FAT partitions exist in one disk. See also +@ref{DOS/Windows}. +@end table +@end deffn + + @node play @subsection play From ca0afd5bab02d1e26dae496435b48647e44e08a8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 13:11:33 +0100 Subject: [PATCH 286/503] * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and per the GNU Coding Standards; this is now too obscure to be worth documenting. (QNX): Likewise. (chainloader): Remove cross-reference to `SCO UnixWare'. --- ChangeLog | 8 ++++++++ docs/grub.texi | 37 +------------------------------------ 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0fc06848..61e4ea8ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and + per the GNU Coding Standards; this is now too obscure to be worth + documenting. + (QNX): Likewise. + (chainloader): Remove cross-reference to `SCO UnixWare'. + 2010-06-02 Colin Watson * docs/grub.texi (Chain-loading): New section. diff --git a/docs/grub.texi b/docs/grub.texi index 5f2e5e36a..1f0c2083e 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -685,8 +685,6 @@ Here, we describe some caveats on several operating systems. * GNU/Hurd:: * GNU/Linux:: * DOS/Windows:: -* SCO UnixWare:: -* QNX:: @end menu @@ -777,38 +775,6 @@ boot @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 -set root=(hd1,1) -chainloader --force +1 -parttool @verb{'${root}'} boot+ -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 -set root=(hd1,2) -chainloader +4 -boot -@end group -@end example - - @node Configuration @chapter Writing your own configuration file @@ -1518,8 +1484,7 @@ filesystem code, it can use the blocklist notation (@pxref{Block list syntax}) 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}). +load a defective boot loader, such as SCO UnixWare 7.1. @end deffn From 0b35b2a9211feafd80a1a203e793a1e68ccbe5a3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 13:57:13 +0100 Subject: [PATCH 287/503] * util/grub.d/00_header.in: Add safety check to make sure that ${locale_dir} exists before trying to probe it. --- ChangeLog | 5 +++++ util/grub.d/00_header.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 61e4ea8ec..fb73905e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * util/grub.d/00_header.in: Add safety check to make sure that + ${locale_dir} exists before trying to probe it. + 2010-06-02 Colin Watson * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index df8f5dfaa..0a5cfac18 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -195,7 +195,7 @@ EOF esac # Gettext variables and module -if [ "x${LANG}" != "xC" ] ; then +if [ "x${LANG}" != "xC" ] && [ -d "${locale_dir}" ] ; then prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) cat << EOF set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) From 11dccbfd4d2ed5e91e5f4f767161a0095ef01025 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:45:43 +0200 Subject: [PATCH 288/503] Sort scsi_cmd_t. --- include/grub/scsicmd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h index f9a7cb200..9cc5afe72 100644 --- a/include/grub/scsicmd.h +++ b/include/grub/scsicmd.h @@ -147,14 +147,14 @@ struct grub_scsi_write12 typedef enum { - grub_scsi_cmd_inquiry = 0x12, grub_scsi_cmd_test_unit_ready = 0x00, + grub_scsi_cmd_request_sense = 0x03, + 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_request_sense = 0x03 } grub_scsi_cmd_t; typedef enum From f0e6cceb813e626d313ae6b15e03683b82b322ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:46:37 +0200 Subject: [PATCH 289/503] Remove leftover early debug exit. --- commands/usbtest.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/commands/usbtest.c b/commands/usbtest.c index 7d1f85cfd..191c4e4df 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -148,8 +148,6 @@ usb_iterate (grub_usb_device_t dev) grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); - return 0; - for (i = 0; i < descdev->configcnt; i++) { struct grub_usb_desc_config *config; From 8bd3a1fb3027c7e05be06d5145bd8d16ee1bcbeb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:46:55 +0200 Subject: [PATCH 290/503] Add necessarry cast --- disk/scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disk/scsi.c b/disk/scsi.c index dffabc26e..5d3e50966 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -460,7 +460,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n", scsi->size, scsi->blocksize); grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n", - disk->total_sectors); + (unsigned long long) disk->total_sectors); return GRUB_ERR_NONE; } From f133a8a74b31c085e68831f76a7e78a8c49629da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:48:10 +0200 Subject: [PATCH 291/503] Enable USB on 64-bit (still won't work with >= 4GiB memory). --- bus/pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bus/pci.c b/bus/pci.c index 3e2126962..1635e889b 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -21,7 +21,8 @@ #include #include -#if GRUB_TARGET_SIZEOF_VOID_P == 4 +/* FIXME: correctly support 64-bit architectures. */ +/* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */ struct grub_pci_dma_chunk * grub_memalign_dma32 (grub_size_t align, grub_size_t size) { @@ -33,7 +34,7 @@ grub_dma_free (struct grub_pci_dma_chunk *ch) { grub_free (ch); } -#endif +/* #endif */ #ifdef GRUB_MACHINE_MIPS_YEELOONG volatile void * From 5d538b8b4a17de54cda284ee1ba081afbef8f978 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:49:22 +0200 Subject: [PATCH 292/503] Use memset --- bus/usb/usb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 7df148333..c872e9276 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -105,10 +105,7 @@ 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) { - int i; - - for (i = 0; i < 256; i++) - dev->toggle[i] = 0; + grub_memset (dev->toggle, 0, sizeof (dev->toggle)); return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_STANDARD From 7db51e329b7e8f0cdeaea60b2fd866105406d9c4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:51:54 +0200 Subject: [PATCH 293/503] Remove double defines and use dma_free --- bus/usb/ohci.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index a42d9fee1..956a27292 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -339,10 +339,8 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: -#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) - grub_free ((void *) o->hcca); -#endif + grub_dma_free (o->hcca_chunk); grub_free (o); return 0; @@ -883,11 +881,6 @@ grub_ohci_transfer (grub_usb_controller_t dev, return err; } -#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) -#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) -#define GRUB_OHCI_SET_PORT_RESET (1 << 4) -#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) - static grub_err_t grub_ohci_portstatus (grub_usb_controller_t dev, unsigned int port, unsigned int enable) From 49396b4f61726411e4d7bfaefbf2f62e93763102 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:52:16 +0200 Subject: [PATCH 294/503] Add ChangeLog --- ChangeLog | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5072a6026..a693e4385 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,122 @@ +2010-06-02 Aleš Nesrsta + + Finally make USB usable. + + * bus/usb/ohci.c (grub_ohci_reg_t): Add missing values. + (GRUB_OHCI_RHUB_PORT_POWER_MASK): New macro. + (GRUB_OHCI_RHUB_PORT_ALL_POWERED): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT): Likewise. + (GRUB_OHCI_FSMPS): Likewise. + (GRUB_OHCI_PERIODIC_START): Likewise. + (GRUB_OHCI_FRAME_INTERVAL): Likewise. + (GRUB_OHCI_SET_PORT_ENABLE): Likewise. + (GRUB_OHCI_CLEAR_PORT_ENABLE): Likewise. + (GRUB_OHCI_SET_PORT_RESET): Likewise. + (GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE): Likewise. + * bus/usb/ohci.c (grub_ohci_pci_iter): Various important fixups. + (grub_ohci_transaction): Likewise. + (grub_ohci_transfer): Improve condition detection algorithms. + Handle toggle property. Program the transactions correctly. + Improve error handling. Various important fixups. + (grub_ohci_portstatus): Put register writes in right order. + * bus/usb/uhci.c (grub_free_queue): Compute last_trans. + (grub_uhci_transfer): Don't show "failed" message on success. + * bus/usb/usb.c (grub_usb_set_configuration): Zero-fill whole "toggle" + array. + (grub_usb_device_initialize): Read first 8 bytes of descriptor to + determine its size. + * bus/usb/usbtrans.c (grub_usb_control_msg): Use descdev.maxsize0 even + before initialization is completed. Use IN direction for empty + transfers. Use last_trans and compute toggle. + * include/grub/usbtrans.h (grub_usb_transfer): New field last_trans. + (GRUB_USB_FEATURE_ENDP_HALT): Correct the value. + (GRUB_USB_FEATURE_DEV_REMOTE_WU): Likewise. + (GRUB_USB_FEATURE_TEST_MODE): Likewise. + * include/grub/usb.h (grub_usb_err_t): New value GRUB_USB_ERR_UNRECOVERABLE. + (grub_usb_device): Increase toggle to 256. + (grub_usbms_subclass_t): New values GRUB_USBMS_SUBCLASS_RBC, + GRUB_USBMS_SUBCLASS_MMC2, GRUB_USBMS_SUBCLASS_UFI and + GRUB_USBMS_SUBCLASS_SFF8070. + * include/grub/scsicmd.h (grub_scsi_test_unit_ready): New structure. + (grub_scsi_inquiry): New member page and alloc_length. + (grub_scsi_request_sense): New structure. + (grub_scsi_request_sense_data): Likewise. + (grub_scsi_read_capacity): New fields logical_block_addr, PMI and + control. + * disk/scsi.c (grub_scsi_request_sense): New function. + (grub_scsi_test_unit_ready): Likewise. + (grub_scsi_inquiry): Fill new fields. + (grub_scsi_read_capacity): Likewise. + (grub_scsi_read10): Add request sense at the end. + (grub_scsi_read12): Likewise. + (grub_scsi_write10): Likewise. + (grub_scsi_write12): Likewise. + (grub_scsi_open): Add Test Unit Ready. + * disk/usbms.c (grub_usbms_finddevs): Check configcnt. + Support additional subclasses. Con't clear halt yet. Activate the + proper config. Calculate LUNs correctly. + (grub_usbms_transfer): Various important fixups. + +2010-06-02 Vladimir Serbinenko + + * bus/pci.c (grub_pci_iterate) [GRUB_MACHINE_MIPS_YEELOONG]: Skip ghosts. + * bus/usb/ohci.c (grub_ohci_portstatus): Handle R/WC correctly. + (grub_ohci_fini_hw): New function. + (grub_ohci_restore_hw): Likewise. + (GRUB_MOD_INIT(ohci)): Register preboot hook. + (GRUB_MOD_FINI(ohci)): Shutdown OHCI. + * term/usb_keyboard.c: Remove include of grub/machine/console.h. + +2010-06-02 Vladimir Serbinenko + + Dedicated DMA allocations. + + * bus/pci.c (grub_memalign_dma32): New function + (grub_dma_free): Likewise. + (grub_dma_get_virt): Likewise. + (grub_dma_get_phys): Likewise. + * bus/usb/ohci.c (grub_ohci): New members hcca_addr and hcca_chunk. + (grub_ohci_pci_iter): Use dma32_alloc. + (grub_ohci_transfer): Likewise. + * bus/usb/usbtrans.c (grub_usb_control_msg): Likewise. + (grub_usb_bulk_readwrite): Likewise. + * include/grub/pci.h: Add declarations. + +2010-06-02 Vladimir Serbinenko + + CS5536 support. + + * bus/cs5536.c: New file. + * bus/usb/ohci.c (grub_ohci_pci_iter): Check for CS5536. + * conf/i386.rmk (pkglib_MODULES): Add cs5536.mod. + (cs5536_mod_SOURCES): New variable. + (cs5536_mod_CFLAGS): Likewise. + (cs5536_mod_LDFLAGS): Likewise. + * conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add cs5536.h and + machine/pci.h. + (kernel_img_SOURCES): Add bus/cs5536.c. + (pkglib_MODULES): Add usb.mod, usbtest.mod, ohci.mod, usbms.mod and + usb_keyboard.mod. + (usb_mod_SOURCES): New variable. + (usb_mod_CFLAGS): New variable. + (usb_mod_LDFLAGS): New variable. + (usbtest_mod_SOURCES): New variable. + (usbtest_mod_CFLAGS): New variable. + (usbtest_mod_LDFLAGS): New variable. + (ohci_mod_SOURCES): New variable. + (ohci_mod_CFLAGS): New variable. + (ohci_mod_LDFLAGS): New variable. + (usbms_mod_SOURCES): New variable. + (usbms_mod_CFLAGS): New variable. + (usbms_mod_LDFLAGS): New variable. + (usb_keyboard_mod_SOURCES): New variable. + (usb_keyboard_mod_CFLAGS): New variable. + (usb_keyboard_mod_LDFLAGS): New variable. + * include/grub/smbus.h: New file. + * include/grub/cs5536.h: New file. + 2010-05-28 Colin Watson * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not From 440ab68551062891c45ce12f4577fb4f7294545e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 19:52:17 +0200 Subject: [PATCH 295/503] Restructure usbms as a preparation for hotplug --- bus/usb/usb.c | 51 +++++++ disk/usbms.c | 325 ++++++++++++++++++++++----------------------- include/grub/usb.h | 20 +++ 3 files changed, 227 insertions(+), 169 deletions(-) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index c872e9276..79a79e644 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -21,6 +21,7 @@ #include #include #include +#include static grub_usb_controller_dev_t grub_usb_list; @@ -232,3 +233,53 @@ grub_usb_device_initialize (grub_usb_device_t dev) return err; } + +struct grub_usb_attach_desc *attach_hooks; + +void +grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc) +{ + auto int usb_iterate (grub_usb_device_t dev); + + int usb_iterate (grub_usb_device_t usbdev) + { + struct grub_usb_desc_device *descdev = &usbdev->descdev; + int i; + + if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 + || descdev->configcnt == 0) + return 0; + + /* XXX: Just check configuration 0 for now. */ + for (i = 0; i < usbdev->config[0].descconf->numif; i++) + { + struct grub_usb_desc_if *interf; + + interf = usbdev->config[0].interf[i].descif; + + grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", + i, interf->class, interf->subclass, interf->protocol); + + if (usbdev->config[0].interf[i].attached) + continue; + + if (interf->class != desc->class) + continue; + if (desc->hook (usbdev, 0, i)) + usbdev->config[0].interf[i].attached = 1; + } + + return 0; + } + + desc->next = attach_hooks; + attach_hooks = desc; + + grub_usb_iterate (usb_iterate); +} + +void +grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc) +{ + grub_list_remove (GRUB_AS_LIST_P (&attach_hooks), GRUB_AS_LIST (desc)); +} diff --git a/disk/usbms.c b/disk/usbms.c index a49b30e7e..84597aa01 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -52,20 +52,19 @@ struct grub_usbms_dev int luns; + int config; 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; +/* FIXME: remove limit. */ +#define MAX_USBMS_DEVICES 128 +static grub_usbms_dev_t grub_usbms_devices[MAX_USBMS_DEVICES]; static grub_err_t grub_usbms_reset (grub_usb_device_t dev, int interface) @@ -74,149 +73,133 @@ grub_usbms_reset (grub_usb_device_t dev, int interface) } static void -grub_usbms_finddevs (void) +grub_usbms_detach (grub_usb_device_t usbdev, int config, int interface) { - auto int usb_iterate (grub_usb_device_t dev); + unsigned i; + for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) + if (grub_usbms_devices[i] && grub_usbms_devices[i]->dev == usbdev + && grub_usbms_devices[i]->interface == interface + && grub_usbms_devices[i]->config == config) + { + grub_free (grub_usbms_devices[i]); + grub_usbms_devices[i] = 0; + } +} - int usb_iterate (grub_usb_device_t usbdev) +static int +grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) +{ + struct grub_usb_desc_if *interf + = usbdev->config[configno].interf[interfno].descif; + int j; + grub_uint8_t luns = 0; + unsigned curnum; + grub_usb_err_t err; + + for (curnum = 0; curnum < ARRAY_SIZE (grub_usbms_devices); curnum++) + if (!grub_usbms_devices[curnum]) + break; + + if (curnum == ARRAY_SIZE (grub_usbms_devices)) + return 0; + + interf = usbdev->config[configno].interf[interfno].descif; + + if ((interf->subclass != GRUB_USBMS_SUBCLASS_BULK + /* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */ + && interf->subclass != GRUB_USBMS_SUBCLASS_RBC + && interf->subclass != GRUB_USBMS_SUBCLASS_MMC2 + && interf->subclass != GRUB_USBMS_SUBCLASS_UFI + && interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 ) + || interf->protocol != GRUB_USBMS_PROTOCOL_BULK) + return 0; + + grub_usbms_devices[curnum] = grub_zalloc (sizeof (struct grub_usbms_dev)); + if (! grub_usbms_devices[curnum]) + return 0; + + grub_usbms_devices[curnum]->dev = usbdev; + grub_usbms_devices[curnum]->interface = interfno; + + grub_dprintf ("usbms", "alive\n"); + + /* Iterate over all endpoints of this interface, at least a + IN and OUT bulk endpoint are required. */ + for (j = 0; j < interf->endpointcnt; j++) { - grub_usb_err_t err; - struct grub_usb_desc_device *descdev = &usbdev->descdev; - int i; + struct grub_usb_desc_endp *endp; + endp = &usbdev->config[0].interf[interfno].descendp[j]; - if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 - || descdev->configcnt == 0) - return 0; - - /* XXX: Just check configuration 0 for now. */ - for (i = 0; i < usbdev->config[0].descconf->numif; i++) + if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2) { - struct grub_usbms_dev *usbms; - struct grub_usb_desc_if *interf; - int j; - grub_uint8_t luns = 0; - - grub_dprintf ("usbms", "alive\n"); - - interf = usbdev->config[0].interf[i].descif; - - /* If this is not a USB Mass Storage device with a supported - protocol, just skip it. */ - grub_dprintf ("usbms", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", - i, interf->class, interf->subclass, interf->protocol); - - if (interf->class != GRUB_USB_CLASS_MASS_STORAGE - || ( interf->subclass != GRUB_USBMS_SUBCLASS_BULK && - /* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */ - interf->subclass != GRUB_USBMS_SUBCLASS_RBC && - interf->subclass != GRUB_USBMS_SUBCLASS_MMC2 && - interf->subclass != GRUB_USBMS_SUBCLASS_UFI && - interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 ) - || interf->protocol != GRUB_USBMS_PROTOCOL_BULK) - { - continue; - } - - grub_dprintf ("usbms", "alive\n"); - - devcnt++; - usbms = grub_zalloc (sizeof (struct grub_usbms_dev)); - if (! usbms) - return 1; - - usbms->dev = usbdev; - usbms->interface = i; - - grub_dprintf ("usbms", "alive\n"); - - /* 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; - /* Clear Halt is not possible yet! */ - /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ - usbms->in_maxsz = endp->maxpacket; - } - else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) - { - /* Bulk OUT endpoint. */ - usbms->out = endp; - /* Clear Halt is not possible yet! */ - /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ - usbms->out_maxsz = endp->maxpacket; - } - } - - if (!usbms->in || !usbms->out) - { - grub_free (usbms); - return 0; - } - - grub_dprintf ("usbms", "alive\n"); - - /* XXX: Activate the first configuration. */ - grub_usb_set_configuration (usbdev, 1); - - /* 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); - grub_usb_clear_halt (usbdev, usbms->out->endp_addr); - } - /* Just set the amount of LUNs to one. */ - grub_errno = GRUB_ERR_NONE; - usbms->luns = 1; - } - else - /* luns = 0 means one LUN with ID 0 present ! */ - /* We get from device not number of LUNs but highest - * LUN number. LUNs are numbered from 0, - * i.e. number of LUNs is luns+1 ! */ - usbms->luns = luns + 1; - - grub_dprintf ("usbms", "alive\n"); - - usbms->next = grub_usbms_dev_list; - grub_usbms_dev_list = usbms; - -#if 0 /* All this part should be probably deleted. - * This make trouble on some devices if they are not in - * Phase Error state - and there they should be not in such state... - * Bulk only mass storage reset procedure should be used only - * on place and in time when it is really necessary. */ - /* Reset recovery procedure */ - /* Bulk-Only Mass Storage Reset, after the reset commands - will be accepted. */ - grub_usbms_reset (usbdev, i); - grub_usb_clear_halt (usbdev, usbms->in->endp_addr); - grub_usb_clear_halt (usbdev, usbms->out->endp_addr); -#endif - - return 0; + /* Bulk IN endpoint. */ + grub_usbms_devices[curnum]->in = endp; + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ + grub_usbms_devices[curnum]->in_maxsz = endp->maxpacket; } + else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) + { + /* Bulk OUT endpoint. */ + grub_usbms_devices[curnum]->out = endp; + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ + grub_usbms_devices[curnum]->out_maxsz = endp->maxpacket; + } + } - grub_dprintf ("usbms", "alive\n"); + if (!grub_usbms_devices[curnum]->in || !grub_usbms_devices[curnum]->out) + { + grub_free (grub_usbms_devices[curnum]); + grub_usbms_devices[curnum] = 0; return 0; } + grub_dprintf ("usbms", "alive\n"); - grub_usb_iterate (usb_iterate); + /* XXX: Activate the first configuration. */ + grub_usb_set_configuration (usbdev, 1); + + /* Query the amount of LUNs. */ + err = grub_usb_control_msg (usbdev, 0xA1, 254, 0, interfno, 1, (char *) &luns); + + if (err) + { + /* In case of a stall, clear the stall. */ + if (err == GRUB_USB_ERR_STALL) + { + grub_usb_clear_halt (usbdev, grub_usbms_devices[curnum]->in->endp_addr); + grub_usb_clear_halt (usbdev, grub_usbms_devices[curnum]->out->endp_addr); + } + /* Just set the amount of LUNs to one. */ + grub_errno = GRUB_ERR_NONE; + grub_usbms_devices[curnum]->luns = 1; + } + else + /* luns = 0 means one LUN with ID 0 present ! */ + /* We get from device not number of LUNs but highest + * LUN number. LUNs are numbered from 0, + * i.e. number of LUNs is luns+1 ! */ + grub_usbms_devices[curnum]->luns = luns + 1; + grub_dprintf ("usbms", "alive\n"); + usbdev->config[configno].interf[interfno].detach_hook = grub_usbms_detach; + +#if 0 /* All this part should be probably deleted. + * This make trouble on some devices if they are not in + * Phase Error state - and there they should be not in such state... + * Bulk only mass storage reset procedure should be used only + * on place and in time when it is really necessary. */ + /* Reset recovery procedure */ + /* Bulk-Only Mass Storage Reset, after the reset commands + will be accepted. */ + grub_usbms_reset (usbdev, i); + grub_usb_clear_halt (usbdev, usbms->in->endp_addr); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr); +#endif + + return 1; } @@ -224,22 +207,21 @@ grub_usbms_finddevs (void) static int grub_usbms_iterate (int (*hook) (const char *name, int luns)) { - grub_usbms_dev_t p; - int cnt = 0; + unsigned i; - for (p = grub_usbms_dev_list; p; p = p->next) - { - char *devname; - devname = grub_xasprintf ("usb%d", cnt); + for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) + if (grub_usbms_devices[i]) + { + char *devname; + devname = grub_xasprintf ("usb%d", i); - if (hook (devname, p->luns)) - { - grub_free (devname); - return 1; - } - grub_free (devname); - cnt++; - } + if (hook (devname, grub_usbms_devices[i]->luns)) + { + grub_free (devname); + return 1; + } + grub_free (devname); + } return 0; } @@ -400,34 +382,24 @@ grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, 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; + if (!grub_usbms_devices[devnum]) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "not a USB Mass Storage device"); - return GRUB_ERR_NONE; - } + scsi->data = grub_usbms_devices[devnum]; + scsi->name = grub_strdup (name); + scsi->luns = grub_usbms_devices[devnum]->luns; + if (! scsi->name) + return grub_errno; - i++; - } - - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "not a USB Mass Storage device"); + return GRUB_ERR_NONE; } static void @@ -446,13 +418,28 @@ static struct grub_scsi_dev grub_usbms_dev = .write = grub_usbms_write }; +struct grub_usb_attach_desc attach_hook = +{ + .class = GRUB_USB_CLASS_MASS_STORAGE, + .hook = grub_usbms_attach +}; + GRUB_MOD_INIT(usbms) { - grub_usbms_finddevs (); + grub_usb_register_attach_hook_class (&attach_hook); grub_scsi_dev_register (&grub_usbms_dev); } GRUB_MOD_FINI(usbms) { + unsigned i; + for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) + { + grub_usbms_devices[i]->dev->config[grub_usbms_devices[i]->config] + .interf[grub_usbms_devices[i]->interface].detach_hook = 0; + grub_usbms_devices[i]->dev->config[grub_usbms_devices[i]->config] + .interf[grub_usbms_devices[i]->interface].attached = 0; + } + grub_usb_unregister_attach_hook_class (&attach_hook); grub_scsi_dev_unregister (&grub_usbms_dev); } diff --git a/include/grub/usb.h b/include/grub/usb.h index 64dc78d61..239905623 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -125,6 +125,13 @@ struct grub_usb_interface struct grub_usb_desc_if *descif; struct grub_usb_desc_endp *descendp; + + /* A driver is handling this interface. Do we need to support multiple drivers + for single interface? + */ + int attached; + + void (*detach_hook) (struct grub_usb_device *dev, int config, int interface); }; struct grub_usb_configuration @@ -207,4 +214,17 @@ grub_usb_get_config_interface (struct grub_usb_desc_config *config) return interf; } +typedef int (*grub_usb_attach_hook_class) (grub_usb_device_t usbdev, + int configno, int interfno); + +struct grub_usb_attach_desc +{ + struct grub_usb_attach_desc *next; + int class; + grub_usb_attach_hook_class hook; +}; + +void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc); +void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc); + #endif /* GRUB_USB_H */ From 5434f8bf3abfb5510c8a78096ecad7e3e03c87ac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 21:54:25 +0200 Subject: [PATCH 296/503] Remove extra empty line --- bus/usb/ohci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 956a27292..47cca7ce4 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -222,7 +222,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - { grub_uint32_t control; /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */ From f5db3949e716e94cb2674aedf38414bd1232616d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 21:54:51 +0200 Subject: [PATCH 297/503] Some hotplug support (buggy) --- bus/usb/usb.c | 22 ++++++++- bus/usb/usbhub.c | 113 ++++++++++++++++++++++++++++++++++++--------- disk/usbms.c | 5 ++ include/grub/usb.h | 2 + 4 files changed, 117 insertions(+), 25 deletions(-) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 79a79e644..9a78f2c4a 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -24,6 +24,7 @@ #include static grub_usb_controller_dev_t grub_usb_list; +struct grub_usb_attach_desc *attach_hooks; void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) @@ -224,6 +225,25 @@ grub_usb_device_initialize (grub_usb_device_t dev) } } + /* XXX: Just check configuration 0 for now. */ + for (i = 0; i < dev->config[0].descconf->numif; i++) + { + struct grub_usb_desc_if *interf; + struct grub_usb_attach_desc *desc; + + interf = dev->config[0].interf[i].descif; + + grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", + i, interf->class, interf->subclass, interf->protocol); + + if (dev->config[0].interf[i].attached) + continue; + + for (desc = attach_hooks; desc; desc = desc->next) + if (interf->class == desc->class && desc->hook (dev, 0, i)) + dev->config[0].interf[i].attached = 1; + } + return GRUB_USB_ERR_NONE; fail: @@ -234,8 +254,6 @@ grub_usb_device_initialize (grub_usb_device_t dev) return err; } -struct grub_usb_attach_desc *attach_hooks; - void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc) { diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 523abf93e..48e3ce592 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -21,10 +21,22 @@ #include #include #include +#include /* USB Supports 127 devices, with device 0 as special case. */ static struct grub_usb_device *grub_usb_devs[128]; +struct grub_usb_hub +{ + struct grub_usb_hub *next; + grub_usb_controller_t controller; + int nports; + grub_usb_speed_t *speed; + grub_usb_device_t dev; +}; + +struct grub_usb_hub *hubs; + /* 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 @@ -137,43 +149,98 @@ grub_usb_add_hub (grub_usb_device_t dev) return GRUB_ERR_NONE; } +static void +attach_root_port (grub_usb_controller_t controller, int portno, + grub_usb_speed_t speed) +{ + grub_usb_device_t dev; + grub_err_t err; + + /* Enable the port. */ + err = controller->dev->portstatus (controller, portno, 0); + if (err) + return; + + /* Enable the port. */ + err = controller->dev->portstatus (controller, portno, 1); + if (err) + return; + + /* Enable the port and create a device. */ + dev = grub_usb_hub_add_dev (controller, speed); + if (! dev) + return; + + /* If the device is a Hub, scan it for more devices. */ + if (dev->descdev.class == 0x09) + grub_usb_add_hub (dev); +} + grub_usb_err_t grub_usb_root_hub (grub_usb_controller_t controller) { - grub_err_t err; - int ports; int i; + struct grub_usb_hub *hub; + + hub = grub_malloc (sizeof (*hub)); + if (!hub) + return GRUB_USB_ERR_INTERNAL; + + hub->next = hubs; + hubs = hub; + hub->controller = grub_malloc (sizeof (*controller)); + if (!hub->controller) + return GRUB_USB_ERR_INTERNAL; + + grub_memcpy (hub->controller, controller, sizeof (*controller)); + hub->dev = 0; /* Query the number of ports the root Hub has. */ - ports = controller->dev->hubports (controller); - - for (i = 0; i < ports; i++) + hub->nports = controller->dev->hubports (controller); + hub->speed = grub_malloc (sizeof (hub->speed[0]) * hub->nports); + if (!hub->speed) { - grub_usb_speed_t speed = controller->dev->detect_dev (controller, i); + grub_free (hub); + return GRUB_USB_ERR_INTERNAL; + } - if (speed != GRUB_USB_SPEED_NONE) - { - grub_usb_device_t dev; + for (i = 0; i < hub->nports; i++) + { + hub->speed[i] = controller->dev->detect_dev (hub->controller, i); - /* 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); - } + if (hub->speed[i] != GRUB_USB_SPEED_NONE) + attach_root_port (hub->controller, i, hub->speed[i]); } return GRUB_USB_ERR_NONE; } +void +grub_usb_poll_devices (void) +{ + struct grub_usb_hub *hub; + + for (hub = hubs; hub; hub = hub->next) + { + int i; + /* Do we have to recheck number of ports? */ + for (i = 0; i < hub->nports; i++) + { + grub_usb_speed_t speed; + + speed = hub->controller->dev->detect_dev (hub->controller, i); + + if (speed == hub->speed[i]) + continue; + + if (hub->speed[i] == GRUB_USB_SPEED_NONE + && speed != GRUB_USB_SPEED_NONE) + attach_root_port (hub->controller, i, speed); + hub->speed[i] = speed; + } + } +} + int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) { diff --git a/disk/usbms.c b/disk/usbms.c index 84597aa01..5550ff770 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -209,6 +209,8 @@ grub_usbms_iterate (int (*hook) (const char *name, int luns)) { unsigned i; + grub_usb_poll_devices (); + for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) if (grub_usbms_devices[i]) { @@ -389,6 +391,9 @@ grub_usbms_open (const char *name, struct grub_scsi *scsi) "not a USB Mass Storage device"); devnum = grub_strtoul (name + 3, NULL, 10); + + grub_usb_poll_devices (); + if (!grub_usbms_devices[devnum]) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a USB Mass Storage device"); diff --git a/include/grub/usb.h b/include/grub/usb.h index 239905623..7c9dba12a 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -227,4 +227,6 @@ struct grub_usb_attach_desc void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc); void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc); +void grub_usb_poll_devices (void); + #endif /* GRUB_USB_H */ From 7a4c893eb046a852fee405949c281febe92113a9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 21:55:29 +0200 Subject: [PATCH 298/503] Poll device in usbtest --- commands/usbtest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commands/usbtest.c b/commands/usbtest.c index 191c4e4df..213288b52 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -194,6 +194,8 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { + grub_usb_poll_devices (); + grub_printf ("USB devices:\n\n"); grub_usb_iterate (usb_iterate); From 0819fec8a1f8820bfdfac08e9c1e188136bedf29 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 22:48:13 +0100 Subject: [PATCH 299/503] * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. Thanks to Jordan Uggla for spotting this. --- ChangeLog | 5 +++++ docs/grub.texi | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 49583746c..8036c7fdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. + Thanks to Jordan Uggla for spotting this. + 2010-06-02 Aleš Nesrsta Finally make USB usable. diff --git a/docs/grub.texi b/docs/grub.texi index 1f0c2083e..d73c03d9b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -877,7 +877,7 @@ Valid terminal output names depend on the platform, but may include @samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot). -The default is to use the platform's native terminal input. +The default is to use the platform's native terminal output. @item GRUB_TERMINAL If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and From 9d9b5833508080ef4146e8fd4db3dcbd91fcf194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Thu, 3 Jun 2010 00:47:22 +0200 Subject: [PATCH 300/503] Handle all possible disk device names for NetBSD. --- ChangeLog | 6 ++++++ kern/emu/hostdisk.c | 41 +++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8036c7fdb..7279197ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-02 Grégoire Sutre + + * kern/emu/hostdisk.c (convert_system_partition_to_system_disk) + [__NetBSD__]: Handle all device names matching /dev/r[a-z]+[0-9][a-z]. + (find_partition_start) [__NetBSD__]: Correct error messages for NetBSD. + 2010-06-02 Colin Watson * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index ae2f7d9ad..fc62cca26 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -413,7 +413,11 @@ devmapper_fail: if (fd == -1) { grub_error (GRUB_ERR_BAD_DEVICE, +# if !defined(__NetBSD__) "cannot open `%s' while attempting to get disk geometry", dev); +# else /* defined(__NetBSD__) */ + "cannot open `%s' while attempting to get disk label", dev); +# endif /* !defined(__NetBSD__) */ return 0; } @@ -425,7 +429,11 @@ devmapper_fail: # endif /* !defined(__NetBSD__) */ { grub_error (GRUB_ERR_BAD_DEVICE, +# if !defined(__NetBSD__) "cannot get disk geometry of `%s'", dev); +# else /* defined(__NetBSD__) */ + "cannot get disk label of `%s'", dev); +# endif /* !defined(__NetBSD__) */ close (fd); return 0; } @@ -1256,22 +1264,28 @@ devmapper_out: return path; #elif defined(__NetBSD__) - /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]". */ + /* NetBSD uses "/dev/r[a-z]+[0-9][a-z]". */ char *path = xstrdup (os_dev); - if (strncmp ("/dev/rwd", path, 8) == 0 || - strncmp ("/dev/rsd", path, 8) == 0 || - strncmp ("/dev/rcd", path, 8) == 0) + if (strncmp ("/dev/r", path, sizeof("/dev/r") - 1) == 0 && + (path[sizeof("/dev/r") - 1] >= 'a' && path[sizeof("/dev/r") - 1] <= 'z') && + strncmp ("fd", path + sizeof("/dev/r") - 1, sizeof("fd") - 1) != 0) /* not a floppy device name */ { - char *q; - q = path + strlen(path) - 1; /* last character */ - if (grub_isalpha(*q) && grub_isdigit(*(q-1))) - { - int rawpart = -1; + char *p; + for (p = path + sizeof("/dev/r"); *p >= 'a' && *p <= 'z'; p++); + if (grub_isdigit(*p)) + { + p++; + if ((*p >= 'a' && *p <= 'z') && (*(p+1) == '\0')) + { + /* path matches the required regular expression and + p points to its last character. */ + int rawpart = -1; # ifdef HAVE_GETRAWPARTITION - rawpart = getrawpartition(); + rawpart = getrawpartition(); # endif /* HAVE_GETRAWPARTITION */ - if (rawpart >= 0) - *q = 'a' + rawpart; + if (rawpart >= 0) + *p = 'a' + rawpart; + } } } return path; @@ -1429,8 +1443,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return name; # else /* defined(__NetBSD__) */ /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are - * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] - * and in particular it cannot be a floppy device. */ + * different, we know that os_dev cannot be a floppy device. */ # endif /* !defined(__NetBSD__) */ start = find_partition_start (os_dev); From 795b593a475327352308dfba23aeb2217599c8df Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 3 Jun 2010 09:48:23 +0100 Subject: [PATCH 301/503] * INSTALL: Document several build requirements for optional features (libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont). --- ChangeLog | 5 +++++ INSTALL | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7279197ee..d67e7efa4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-03 Colin Watson + + * INSTALL: Document several build requirements for optional features + (libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont). + 2010-06-02 Grégoire Sutre * kern/emu/hostdisk.c (convert_system_partition_to_system_disk) diff --git a/INSTALL b/INSTALL index 7186d20db..44a442253 100644 --- a/INSTALL +++ b/INSTALL @@ -19,6 +19,21 @@ configuring the GRUB. * Flex 2.5.35 or later * Other standard GNU/Unix tools +On GNU/Linux, you also need: + +* libdevmapper (recommended) + +To build grub-emu, you need: + +* ncurses +* libusb (recommended) +* SDL (recommended) + +To build GRUB's graphical terminal (gfxterm), you need: + +* FreeType 2 or later +* GNU Unifont + If you use a development snapshot or want to hack on GRUB you may need the following. From 9cdfe32f0916b227ed0ae1211bc1089684063207 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Jun 2010 13:38:10 +0100 Subject: [PATCH 302/503] * util/grub-mkimage.c: Make target-related error messages slightly more helpful; -O talks about "format". Explicitly point to the use of -O if no target is specified. Reported by: Didier Raboud (Debian bug #584415). --- ChangeLog | 7 +++++++ util/grub-mkimage.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d67e7efa4..fd2f8ae72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-04 Colin Watson + + * util/grub-mkimage.c: Make target-related error messages slightly + more helpful; -O talks about "format". Explicitly point to the use + of -O if no target is specified. + Reported by: Didier Raboud (Debian bug #584415). + 2010-06-03 Colin Watson * INSTALL: Document several build requirements for optional features diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 6366a9803..4e39450df 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1253,7 +1253,7 @@ main (int argc, char *argv[]) image_target = &image_targets[i]; if (!image_target) { - printf ("unknown target %s\n", optarg); + printf ("unknown target format %s\n", optarg); usage (1); } break; @@ -1322,7 +1322,7 @@ main (int argc, char *argv[]) if (!image_target) { - printf ("Target not specified.\n"); + printf ("Target format not specified (use the -O option).\n"); usage (1); } From f28a9212b4465c2b106b4abd057779ddc3c69b3b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Jun 2010 13:53:30 +0100 Subject: [PATCH 303/503] =?UTF-8?q?*=20util/grub-mkconfig=5Flib.in=20(prep?= =?UTF-8?q?are=5Fgrub=5Fto=5Faccess=5Fdevice):=20Prepend=20"part=5F"=20to?= =?UTF-8?q?=20partmap=20module=20names,=20in=20line=20with=20grub-install.?= =?UTF-8?q?=20Reported=20by:=20Jind=C5=99ich=20Makovi=C4=8Dka=20(Debian=20?= =?UTF-8?q?bug=20#584426).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fd2f8ae72..65a3c69b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-04 Colin Watson + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend + "part_" to partmap module names, in line with grub-install. + Reported by: Jindřich Makovička (Debian bug #584426). + 2010-06-04 Colin Watson * util/grub-mkimage.c: Make target-related error messages slightly diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 7ec8cb5be..14ea1842f 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -107,7 +107,7 @@ prepare_grub_to_access_device () partmap="`${grub_probe} --device ${device} --target=partmap`" for module in ${partmap} ; do - echo "insmod ${module}" + echo "insmod part_${module}" done fs="`${grub_probe} --device ${device} --target=fs`" From 71c3809882f5382ef40e434c7ac1a76d020f3577 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 5 Jun 2010 20:44:44 +0100 Subject: [PATCH 304/503] * util/grub.d/00_header.in: Quote values assigned to `saved_entry', in case they contain spaces. --- ChangeLog | 5 +++++ util/grub.d/00_header.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65a3c69b8..779973f1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-05 Colin Watson + + * util/grub.d/00_header.in: Quote values assigned to `saved_entry', + in case they contain spaces. + 2010-06-04 Colin Watson * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0a5cfac18..199a1d7af 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -62,7 +62,7 @@ EOF fi cat < Date: Mon, 7 Jun 2010 14:15:57 +0100 Subject: [PATCH 305/503] * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable to `count', fixing variable shadowing that broke the -c option. --- ChangeLog | 7 ++++++- util/grub-mkpasswd-pbkdf2.c | 9 +++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 779973f1e..07c262dc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2010-06-05 Colin Watson +2010-06-07 Colin Watson + + * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable + to `count', fixing variable shadowing that broke the -c option. + +2010-06-05 Colin Watson * util/grub.d/00_header.in: Quote values assigned to `saved_entry', in case they contain spaces. diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index a00b1e990..944c6c46a 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -112,7 +112,7 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n) int main (int argc, char *argv[]) { - unsigned int c = 10000, buflen = 64, saltlen = 64; + unsigned int count = 10000, buflen = 64, saltlen = 64; char *pass1, *pass2; char *bufhex, *salthex; gcry_err_code_t gcry_err; @@ -137,7 +137,7 @@ main (int argc, char *argv[]) switch (c) { case 'c': - c = strtoul (optarg, NULL, 0); + count = strtoul (optarg, NULL, 0); break; case 'l': @@ -307,7 +307,7 @@ main (int argc, char *argv[]) gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) pass1, strlen (pass1), salt, saltlen, - c, buf, buflen); + count, buf, buflen); memset (pass1, 0, strlen (pass1)); free (pass1); @@ -327,7 +327,8 @@ main (int argc, char *argv[]) hexify (bufhex, buf, buflen); hexify (salthex, salt, saltlen); - printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", c, salthex, bufhex); + printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", + count, salthex, bufhex); memset (buf, 0, buflen); memset (bufhex, 0, 2 * buflen); free (buf); From e1cbcc40a45e7fe0f5d0dbf42a2815eb7b832efe Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 14:22:40 +0100 Subject: [PATCH 306/503] * util/grub.d/00_header.in: Add some more quoting (of "${prev_saved_entry}" and "${boot_once}") needed to make savedefault work again. Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812). --- ChangeLog | 7 +++++++ util/grub.d/00_header.in | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07c262dc2..5568cbd3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * util/grub.d/00_header.in: Add some more quoting (of + "${prev_saved_entry}" and "${boot_once}") needed to make savedefault + work again. + Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812). + 2010-06-07 Colin Watson * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 199a1d7af..791840a60 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -61,7 +61,7 @@ set default="${GRUB_DEFAULT}" EOF fi cat < Date: Mon, 7 Jun 2010 14:32:12 +0100 Subject: [PATCH 307/503] * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. (password): New section. (password_pbkdf2): New section. (search): New section. (Security): New section. (Troubleshooting): New section, currently very incomplete. (Invoking grub-mkpasswd-pbkdf2): New section. (Internals): New section, currently very incomplete. --- ChangeLog | 11 ++ docs/grub.texi | 317 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 326 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5568cbd3a..3a3df4c5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. + (password): New section. + (password_pbkdf2): New section. + (search): New section. + (Security): New section. + (Troubleshooting): New section, currently very incomplete. + (Invoking grub-mkpasswd-pbkdf2): New section. + (Internals): New section, currently very incomplete. + 2010-06-07 Colin Watson * util/grub.d/00_header.in: Add some more quoting (of diff --git a/docs/grub.texi b/docs/grub.texi index d73c03d9b..837607d62 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -35,6 +35,7 @@ Invariant Sections. * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive * grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration +* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. @end direntry @setchapternewpage odd @@ -84,9 +85,12 @@ This edition documents version @value{VERSION}. * Filesystem:: Filesystem syntax and semantics * Interface:: The menu and the command-line * Commands:: The list of available builtin commands +* Security:: Authentication and authorisation * Troubleshooting:: Error messages produced by GRUB * Invoking grub-install:: How to use the GRUB installer * Invoking grub-mkconfig:: Generate a GRUB configuration file +* Invoking grub-mkpasswd-pbkdf2:: + Generate GRUB password hashes * 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 @@ -1041,8 +1045,8 @@ 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}). +you see the files in a device or use the command @command{search} +(@pxref{search}). @menu * Device syntax:: How to specify devices @@ -1415,8 +1419,11 @@ you forget a command, you can run the command @command{help} * keystatus:: Check key modifier status * ls:: List devices or files * parttool:: Modify partition table entries +* password:: Set a clear-text password +* password_pbkdf2:: Set a hashed password * play:: Play a tune * reboot:: Reboot your computer +* search:: Search devices by file, label, or UUID * set:: Set an environment variable * unset:: Unset an environment variable @end menu @@ -1747,6 +1754,25 @@ Wwindows and multiple primary FAT partitions exist in one disk. See also @end deffn +@node password +@subsection password + +@deffn Command password user clear-password +Define a user named @var{user} with password @var{clear-password}. +@xref{Security}. +@end deffn + + +@node password_pbkdf2 +@subsection password_pbkdf2 + +@deffn Command password_pbkdf2 user hashed-password +Define a user named @var{user} with password hash @var{hashed-password}. +Use @command{grub-mkpasswd-pbkdf2} (@pxref{Invoking grub-mkpasswd-pbkdf2}) +to generate password hashes. @xref{Security}. +@end deffn + + @node play @subsection play @@ -1774,6 +1800,29 @@ Reboot the computer. @end deffn +@node search +@subsection search + +@deffn Command search @ + [@option{--file}|@option{--label}|@option{--fs-uuid}] @ + [@option{--set} var] [@option{--no-floppy}] name +Search devices by file (@option{-f}, @option{--file}), filesystem label +(@option{-l}, @option{--label}), or filesystem UUID (@option{-u}, +@option{--fs-uuid}). + +If the @option{--set} option is used, the first device found is set as the +value of environment variable @var{var}. The default variable is +@samp{root}. + +The @option{--no-floppy} option prevents searching floppy devices, which can +be slow. + +The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid} +commands are aliases for @samp{search --file}, @samp{search --label}, and +@samp{search --fs-uuid} respectively. +@end deffn + + @node set @subsection set @@ -1791,6 +1840,135 @@ Unset the environment variable @var{envvar}. @end deffn +@node Security +@chapter Authentication and authorisation + +By default, the boot loader interface is accessible to anyone with physical +access to the console: anyone can select and edit any menu entry, and anyone +can get direct access to a GRUB shell prompt. For most systems, this is +reasonable since anyone with direct physical access has a variety of other +ways to gain full access, and requiring authentication at the boot loader +level would only serve to make it difficult to recover broken systems. + +However, in some environments, such as kiosks, it may be appropriate to lock +down the boot loader to require authentication before performing certain +operations. + +The @samp{password} (@pxref{password}) and @samp{password_pbkdf2} +(@pxref{password_pbkdf2}) commands can be used to define users, each of +which has an associated password. @samp{password} sets the password in +plain text, requiring @file{grub.cfg} to be secure; @samp{password_pbkdf2} +sets the password hashed using the Password-Based Key Derivation Function +(RFC 2898), requiring the use of @command{grub-mkpasswd-pbkdf2} +(@pxref{Invoking grub-mkpasswd-pbkdf2}) to generate password hashes. + +In order to enable authentication support, the @samp{superusers} environment +variable must be set to a list of usernames, separated by any of spaces, +commas, semicolons, pipes, or ampersands. Superusers are permitted to use +the GRUB command line, edit menu entries, and execute any menu entry. + +Other users may be given access to specific menu entries by giving a list of +usernames (as above) using the @kbd{--users} option to the @samp{menuentry} +command (@pxref{menuentry}). + +Putting this together, a typical @file{grub.cfg} fragment might look like +this: + +@example +@group +set superusers="root" +password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring +password user1 insecure + +menuentry "Superusers only" @{ + set root=(hd0,1) + linux /vmlinuz +@} + +menuentry "May be run by user1" --users user1 @{ + set root=(hd0,2) + chainloader +1 +@} +@end group +@end example + +The @command{grub-mkconfig} program does not yet have built-in support for +generating configuration files with authentication. You can use +@file{/etc/grub.d/40_custom} to add simple superuser authentication, by +adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} +commands. + + +@node Troubleshooting +@chapter Error messages produced by GRUB + +@menu +* GRUB only offers a rescue shell:: +@end menu + + +@node GRUB only offers a rescue shell +@section GRUB only offers a rescue shell + +GRUB's normal start-up procedure involves setting the @samp{prefix} +environment variable to a value set in the core image by +@command{grub-install}, setting the @samp{root} variable to match, loading +the @samp{normal} module from the prefix, and running the @samp{normal} +command. This command is responsible for reading +@file{/boot/grub/grub.cfg}, running the menu, and doing all the useful +things GRUB is supposed to do. + +If, instead, you only get a rescue shell, this usually means that GRUB +failed to load the @samp{normal} module for some reason. It may be possible +to work around this temporarily: for instance, if the reason for the failure +is that @samp{prefix} is wrong (perhaps it refers to the wrong device, or +perhaps the path to @file{/boot/grub} was not correctly made relative to the +device), then you can correct this and enter normal mode manually: + +@example +@group +# Inspect the current prefix: +echo @verb{'${prefix}'} +# Set to the correct value, which might be something like this: +set prefix=(hd0,1)/grub +set root=(hd0,1) +insmod normal +normal +@end group +@end example + +However, any problem that leaves you in the rescue shell probably means that +GRUB was not correctly installed. It may be more useful to try to reinstall +it properly using @kbd{grub-install @var{device}} (@pxref{Invoking +grub-install}). When doing this, there are a few things to remember: + +@itemize @bullet{} +@item +Drive ordering in your operating system may not be the same as the boot +drive ordering used by your firmware. Do not assume that your first hard +drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from. + +@item +At least on BIOS systems, if you tell @command{grub-install} to install GRUB +to a partition but GRUB has already been installed in the master boot +record, then the GRUB installation in the partition will be ignored. + +@item +If possible, it is generally best to avoid installing GRUB to a partition +(unless it is a special partition for the use of GRUB alone, such as the +BIOS Boot Partition used on GPT). Doing this means that GRUB may stop being +able to read its core image due to a file system moving blocks around, such +as while defragmenting, running checks, or even during normal operation. +Installing to the whole disk device is normally more robust. + +@item +Check that GRUB actually knows how to read from the device and file system +containing @file{/boot/grub}. It will not be able to read from encrypted +devices, nor from file systems for which support has not yet been added to +GRUB. +@end itemize + + @node Invoking grub-install @chapter Invoking grub-install @@ -1858,6 +2036,34 @@ it to standard output. @end table +@node Invoking grub-mkpasswd-pbkdf2 +@chapter Invoking grub-mkpasswd-pbkdf2 + +The program @command{grub-mkpasswd-pbkdf2} generates password hashes for +GRUB (@pxref{Security}). + +@example +grub-mkpasswd-pbkdf2 +@end example + +@command{grub-mkpasswd-pbkdf2} accepts the following options: + +@table @option +@item -c @var{number} +@itemx --iteration-count=@var{number} +Number of iterations of the underlying pseudo-random function. Defaults to +10000. + +@item -l @var{number} +@itemx --buflen=@var{number} +Length of the generated hash. Defaults to 64. + +@item -s @var{number} +@itemx --salt=@var{number} +Length of the salt. Defaults to 64. +@end table + + @node Obtaining and Building GRUB @appendix How to obtain and build GRUB @@ -1976,6 +2182,113 @@ a look at @uref{http://www.gnu.org/software/grub/grub.html, the homepage}. +@node Internals +@appendix Hacking GRUB + +@menu +* Getting the source code:: +* Finding your way around:: +@end menu + + +@node Getting the source code +@section Getting the source code + +GRUB is maintained using the @uref{http://bazaar-vcs.org/, Bazaar revision +control system}. To fetch the primary development branch: + +@example +bzr get http://bzr.savannah.gnu.org/r/grub/trunk/grub +@end example + +The GRUB developers maintain several other branches with work in progress. +Of these, the most interesting is the experimental branch, which is a +staging area for new code which we expect to eventually merge into trunk but +which is not yet ready: + +@example +bzr get http://bzr.savannah.gnu.org/r/grub/branches/experimental +@end example + +Once you have used @kbd{bzr get} to fetch an initial copy of a branch, you +can use @kbd{bzr pull} to keep it up to date. If you have modified your +local version, you may need to resolve conflicts when pulling. + + +@node Finding your way around +@section Finding your way around + +Here is a brief map of the GRUB code base. + +GRUB uses Autoconf, but not (yet) Automake. The top-level build rules are +in @file{configure.ac}, @file{Makefile.in}, and @file{conf/*.rmk}. Each +@file{conf/*.rmk} file represents a particular target configuration, and is +processed into GNU Make rules by @file{genmk.rb} (which you only need to +look at if you are extending the build system). If you are adding a new +module which follows an existing pattern, such as a new command or a new +filesystem implementation, it is usually easiest to grep @file{conf/*.rmk} +for an existing example of that pattern to find out where it should be +added. + +Low-level boot code, such as the MBR implementation on PC BIOS systems, is +in the @file{boot/} directory. + +The GRUB kernel is in @file{kern/}. This contains core facilities such as +the device, disk, and file frameworks, environment variable handling, list +processing, and so on. The kernel should contain enough to get up to a +rescue prompt. Header files for kernel facilities, among others, are in +@file{include/}. + +Terminal implementations are in @file{term/}. + +Disk access code is spread across @file{disk/} (for accessing the disk +devices themselves), @file{partmap/} (for interpreting partition table +data), and @file{fs/} (for accessing filesystems). Note that, with the odd +specialised exception, GRUB only contains code to @emph{read} from +filesystems and tries to avoid containing any code to @emph{write} to +filesystems; this lets us confidently assure users that GRUB cannot be +responsible for filesystem corruption. + +PCI and USB bus handling is in @file{bus/}. + +Video handling code is in @file{video/}. The graphical menu system uses +this heavily, but is in a separate directory, @file{gfxmenu/}. + +Most commands are implemented by files in @file{commands/}, with the +following exceptions: + +@itemize +@item +A few core commands live in @file{kern/corecmd.c}. + +@item +Commands related to normal mode live under @file{normal/}. + +@item +Commands that load and boot kernels live under @file{loader/}. + +@item +The @samp{loopback} command is really a disk device, and so lives in +@file{disk/loopback.c}. + +@item +The @samp{gettext} command lives under @file{gettext/}. + +@item +The @samp{loadfont} and @samp{lsfonts} commands live under @file{font/}. + +@item +The @samp{serial}, @samp{terminfo}, and @samp{background_image} commands +live under @file{term/}. + +@item +The @samp{efiemu_*} commands live under @file{efiemu/}. +@end itemize + +There are a few other special-purpose exceptions; grep for them if they +matter to you. + + @node Copying This Manual @appendix Copying This Manual From a6a700aa52768f6392337ddbb8798f99a895a018 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:10:29 +0100 Subject: [PATCH 308/503] * docs/grub.texi (Troubleshooting): `echo' is not usually available in the rescue shell, so recommend using `set' instead. Thanks, Jordan Uggla. --- ChangeLog | 6 ++++++ docs/grub.texi | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a3df4c5d..ddb55f17a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Troubleshooting): `echo' is not usually available + in the rescue shell, so recommend using `set' instead. Thanks, + Jordan Uggla. + 2010-06-07 Colin Watson * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. diff --git a/docs/grub.texi b/docs/grub.texi index 837607d62..f2d0c41bf 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1927,8 +1927,8 @@ device), then you can correct this and enter normal mode manually: @example @group -# Inspect the current prefix: -echo @verb{'${prefix}'} +# Inspect the current prefix (and other preset variables): +set # Set to the correct value, which might be something like this: set prefix=(hd0,1)/grub set root=(hd0,1) From ee75515e69598e0c4e6f53c24b3b8247e4a83170 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:26:30 +0100 Subject: [PATCH 309/503] * docs/grub.texi (Network): New section. (Device syntax): The network device is called `(pxe)' in GRUB 2, not `(nd)' as in GRUB Legacy. (pxe_unload): New section. --- ChangeLog | 7 +++++ docs/grub.texi | 85 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ddb55f17a..f9a0d2424 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Network): New section. + (Device syntax): The network device is called `(pxe)' in GRUB 2, not + `(nd)' as in GRUB Legacy. + (pxe_unload): New section. + 2010-06-07 Colin Watson * docs/grub.texi (Troubleshooting): `echo' is not usually available diff --git a/docs/grub.texi b/docs/grub.texi index f2d0c41bf..37016b175 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -970,6 +970,78 @@ that file, making sure to leave at least the first two lines intact. @section Writing full configuration files directly +@node Network +@chapter Booting GRUB from the network + +The following instructions only work on PC BIOS systems where the Preboot +eXecution Environment (PXE) is available. + +To generate a PXE boot image, run: + +@example +@group +grub-mkimage --format=i386-pc --output=core.img --prefix='(pxe)/boot/grub' pxe pxecmd +cat /boot/grub/pxeboot.img core.img >grub.pxe +@end group +@end example + +Copy @file{grub.pxe}, @file{/boot/grub/*.mod}, and @file{/boot/grub/*.lst} +to the PXE (TFTP) server, ensuring that @file{*.mod} and @file{*.lst} are +accessible via the @file{/boot/grub/} path from the TFTP server root. Set +the DHCP server configuration to offer @file{grub.pxe} as the boot file (the +@samp{filename} option in ISC dhcpd). + +After GRUB has started, files on the TFTP server will be accessible via the +@samp{(pxe)} device. + +The server and gateway IP address can be controlled by changing the +@samp{(pxe)} device name to @samp{(pxe:@var{server-ip})} or +@samp{(pxe:@var{server-ip}:@var{gateway-ip})}. Note that this should be +changed both in the prefix and in any references to the device name in the +configuration file. + +GRUB provides several environment variables which may be used to inspect or +change the behaviour of the PXE device: + +@table @samp +@item net_pxe_ip +The IP address of this machine. Read-only. + +@item net_pxe_mac +The network interface's MAC address. Read-only. + +@item net_pxe_hostname +The client host name provided by DHCP. Read-only. + +@item net_pxe_domain +The client domain name provided by DHCP. Read-only. + +@item net_pxe_rootpath +The path to the client's root disk provided by DHCP. Read-only. + +@item net_pxe_extensionspath +The path to additional DHCP vendor extensions provided by DHCP. Read-only. + +@item net_pxe_boot_file +The boot file name provided by DHCP. Read-only. + +@item net_pxe_dhcp_server_name +The name of the DHCP server responsible for these boot parameters. +Read-only. + +@item net_pxe_blksize +The PXE transfer block size. Read-write, defaults to 512. + +@item pxe_default_server +The default PXE server. Read-write, although setting this is only useful +before opening a PXE device. + +@item pxe_default_gateway +The default gateway to use when contacting the PXE server. Read-write, +although setting this is only useful before opening a PXE device. +@end table + + @node Serial terminal @chapter Using GRUB via a serial line @@ -1094,7 +1166,7 @@ MBR when installing GRUB), while the syntax @samp{(hd0,1)} 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 +If you enabled the network support, the special drive @samp{(pxe)} is also available. Before using the network drive, you must initialize the network. @xref{Network}, for more information. @@ -1422,6 +1494,7 @@ you forget a command, you can run the command @command{help} * password:: Set a clear-text password * password_pbkdf2:: Set a hashed password * play:: Play a tune +* pxe_unload:: Unload the PXE environment * reboot:: Reboot your computer * search:: Search devices by file, label, or UUID * set:: Set an environment variable @@ -1792,6 +1865,16 @@ a rest. @end deffn +@node pxe_unload +@subsection pxe_unload + +@deffn Command pxe_unload +Unload the PXE environment (@pxref{Network}). + +This command is only available on PC BIOS systems. +@end deffn + + @node reboot @subsection reboot From 258c2573a659c3b04b2873bcc3da9351a08e8f9a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:29:25 +0100 Subject: [PATCH 310/503] * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. --- ChangeLog | 4 ++++ fs/i386/pc/pxe.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f9a0d2424..b8f5f80d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-07 Colin Watson + + * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. + 2010-06-07 Colin Watson * docs/grub.texi (Network): New section. diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 82d8ee583..e4d481a8e 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -114,7 +114,7 @@ grub_pxe_open (const char *name, grub_disk_t disk) return err; if (*ptr == ':') { - err = parse_ip (ptr + 1, &(data->server_ip), 0); + err = parse_ip (ptr + 1, &(data->gateway_ip), 0); if (err) return err; } From fb55c3acf9adec8a576e35551a8d2f5d6684cb88 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:13:26 +0100 Subject: [PATCH 311/503] * normal/completion.c (grub_normal_do_completion): When completing arguments to "set" and the current word contains an equals sign, skip to after the equals sign before starting completion. --- ChangeLog | 6 ++++++ normal/completion.c | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index b8f5f80d8..bc1b2686a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-07 Colin Watson + + * normal/completion.c (grub_normal_do_completion): When completing + arguments to "set" and the current word contains an equals sign, + skip to after the equals sign before starting completion. + 2010-06-07 Colin Watson * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. diff --git a/normal/completion.c b/normal/completion.c index 13e8f7a6b..334eaea11 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -414,6 +414,14 @@ grub_normal_do_completion (char *buf, int *restore, else current_word = argv[argc - 1]; + if (argc > 1 && ! grub_strcmp (argv[0], "set")) + { + char *equals = grub_strchr (current_word, '='); + if (equals) + /* Complete the value of the variable. */ + current_word = equals + 1; + } + /* Determine the state the command line is in, depending on the state, it can be determined how to complete. */ cmdline_state = get_state (buf); From da90820083ca2a6ca22877068a9d7262cd5629ac Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:18:00 +0100 Subject: [PATCH 312/503] * docs/grub.texi (Naming convention): Use GRUB 2 syntax. (File name syntax): Likewise. (help): --all is no longer supported in GRUB 2. Be more precise about pattern matching. --- ChangeLog | 7 +++++++ docs/grub.texi | 22 ++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc1b2686a..3a463ab42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Naming convention): Use GRUB 2 syntax. + (File name syntax): Likewise. + (help): --all is no longer supported in GRUB 2. Be more precise + about pattern matching. + 2010-06-07 Colin Watson * normal/completion.c (grub_normal_do_completion): When completing diff --git a/docs/grub.texi b/docs/grub.texi index 37016b175..ffc6b8fe2 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -390,14 +390,14 @@ 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,3)}. To help you find out which number -specifies a partition you want, the GRUB command-line +need to use the device specification in a command, like @samp{set +root=(fd0)} or @samp{parttool (hd0,3) hidden-}. 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 ( +set root=( @end example followed by a @key{TAB}, and GRUB will display the list of drives, @@ -1186,8 +1186,8 @@ example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file @file{/boot/grub/grub.cfg} 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,1)} by the command @command{root} (@pxref{root}), then -@code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. +say, @samp{(hd1,1)} by the command @samp{set root=(hd1,1)} (@pxref{set}), +then @code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. @node Block list syntax @@ -1742,15 +1742,13 @@ is shut down using APM. @node help @subsection help -@deffn Command help @option{--all} [pattern @dots{}] +@deffn Command help [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. +specify @var{pattern}, this command shows short descriptions of all +available commands. If you specify any @var{patterns}, it displays longer information -about each of the commands which match those @var{patterns}. +about each of the commands whose names begin with those @var{patterns}. @end deffn From e0f4c438823f1fa82cac8098469cc138bb1fe37d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:41:55 +0100 Subject: [PATCH 313/503] * kern/emu/misc.c (device_mapper_null_log): New function. (grub_device_mapper_supported): New function. * include/grub/emu/misc.h (grub_device_mapper_supported): Add prototype. * kern/emu/hostdisk.c (find_partition_start): Check whether device-mapper is supported before trying to use it. * util/deviceiter.c (grub_util_iterate_devices): Likewise. --- ChangeLog | 10 +++ include/grub/emu/misc.h | 4 + kern/emu/hostdisk.c | 2 +- kern/emu/misc.c | 39 ++++++++ util/deviceiter.c | 194 ++++++++++++++++++++-------------------- 5 files changed, 152 insertions(+), 97 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a463ab42..c28f77bc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-06-07 Colin Watson + + * kern/emu/misc.c (device_mapper_null_log): New function. + (grub_device_mapper_supported): New function. + * include/grub/emu/misc.h (grub_device_mapper_supported): Add + prototype. + * kern/emu/hostdisk.c (find_partition_start): Check whether + device-mapper is supported before trying to use it. + * util/deviceiter.c (grub_util_iterate_devices): Likewise. + 2010-06-07 Colin Watson * docs/grub.texi (Naming convention): Use GRUB 2 syntax. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 0e6ace0e8..f34cd4287 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -48,4 +48,8 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); extern char * canonicalize_file_name (const char *path); +#ifdef HAVE_DEVICE_MAPPER +int grub_device_mapper_supported (void); +#endif + #endif /* GRUB_EMU_MISC_H */ diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index fc62cca26..47389195c 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -342,7 +342,7 @@ find_partition_start (const char *dev) # endif /* !defined(__NetBSD__) */ # ifdef HAVE_DEVICE_MAPPER - if (device_is_mapped (dev)) { + if (grub_device_mapper_supported () && device_is_mapped (dev)) { struct dm_task *task = NULL; grub_uint64_t start, length; char *target_type, *params, *space; diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 9437169e0..38395fca8 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -22,6 +22,10 @@ #include #include +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + int verbosity; void @@ -311,3 +315,38 @@ grub_make_system_path_relative_to_its_root (const char *path) return buf3; } + +#ifdef HAVE_DEVICE_MAPPER +static void device_mapper_null_log (int level __attribute__ ((unused)), + const char *file __attribute__ ((unused)), + int line __attribute__ ((unused)), + int dm_errno __attribute__ ((unused)), + const char *f __attribute__ ((unused)), + ...) +{ +} + +int +grub_device_mapper_supported (void) +{ + static int supported = -1; + + if (supported == -1) + { + struct dm_task *dmt; + + /* Suppress annoying log messages. */ + dm_log_with_errno_init (&device_mapper_null_log); + + dmt = dm_task_create (DM_DEVICE_VERSION); + supported = (dmt != NULL); + if (dmt) + dm_task_destroy (dmt); + + /* Restore the original logger. */ + dm_log_with_errno_init (NULL); + } + + return supported; +} +#endif /* HAVE_DEVICE_MAPPER */ diff --git a/util/deviceiter.c b/util/deviceiter.c index 03813bc7d..d7e8f159e 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef __linux__ # if !defined(__GLIBC__) || \ @@ -676,112 +677,113 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), } /* DM-RAID. */ - { - struct dm_tree *tree = NULL; - struct dm_task *task = NULL; - struct dm_names *names = NULL; - unsigned int next = 0; - void *top_handle, *second_handle; - struct dm_tree_node *root, *top, *second; - struct dmraid_seen *seen = NULL; + if (grub_device_mapper_supported ()) + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + struct dmraid_seen *seen = NULL; - /* Build DM tree for all devices. */ - tree = dm_tree_create (); - dmraid_check (tree, "dm_tree_create failed\n"); - task = dm_task_create (DM_DEVICE_LIST); - dmraid_check (task, "dm_task_create failed\n"); - dmraid_check (dm_task_run (task), "dm_task_run failed\n"); - names = dm_task_get_names (task); - dmraid_check (names, "dm_task_get_names failed\n"); - dmraid_check (names->dev, "No DM devices found\n"); - do - { - names = (void *) names + next; - dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), - MINOR (names->dev)), - "dm_tree_add_dev (%s) failed\n", names->name); - next = names->next; - } - while (next); + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (void *) names + next; + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); - /* Walk the second-level children of the inverted tree; that is, devices - which are directly composed of non-DM devices such as hard disks. - This class includes all DM-RAID disks and excludes all DM-RAID - partitions. */ - root = dm_tree_find_node (tree, 0, 0); - top_handle = NULL; - top = dm_tree_next_child (&top_handle, root, 1); - while (top) - { - second_handle = NULL; - second = dm_tree_next_child (&second_handle, top, 1); - while (second) - { - const char *node_name, *node_uuid; - char *name; - struct dmraid_seen *seen_elt; + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + struct dmraid_seen *seen_elt; - node_name = dm_tree_node_get_name (second); - dmraid_check (node_name, "dm_tree_node_get_name failed\n"); - node_uuid = dm_tree_node_get_uuid (second); - dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); - if (strncmp (node_uuid, "DMRAID-", 7) != 0) - { - grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); - goto dmraid_next_child; - } + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } - /* Have we already seen this node? There are typically very few - DM-RAID disks, so a list should be fast enough. */ - if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) - { - grub_dprintf ("deviceiter", "Already seen DM device %s\n", - node_name); - goto dmraid_next_child; - } + /* Have we already seen this node? There are typically very few + DM-RAID disks, so a list should be fast enough. */ + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) + { + grub_dprintf ("deviceiter", "Already seen DM device %s\n", + node_name); + goto dmraid_next_child; + } - name = xasprintf ("/dev/mapper/%s", node_name); - if (check_device (name)) - { - if (hook (name, 0)) - { - free (name); - while (seen) - { - struct dmraid_seen *seen_elt = - grub_list_pop (GRUB_AS_LIST_P (&seen)); - free (seen_elt); - } - if (task) - dm_task_destroy (task); - if (tree) - dm_tree_free (tree); - return; - } - } - free (name); + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device (name)) + { + if (hook (name, 0)) + { + free (name); + while (seen) + { + struct dmraid_seen *seen_elt = + grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + return; + } + } + free (name); - seen_elt = xmalloc (sizeof *seen_elt); - seen_elt->name = node_name; - grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + seen_elt = xmalloc (sizeof *seen_elt); + seen_elt->name = node_name; + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); dmraid_next_child: - second = dm_tree_next_child (&second_handle, top, 1); - } - top = dm_tree_next_child (&top_handle, root, 1); - } + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } dmraid_end: - while (seen) - { - struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); - free (seen_elt); - } - if (task) - dm_task_destroy (task); - if (tree) - dm_tree_free (tree); - } + while (seen) + { + struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } # endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ } From 6ef0ddb4760e58f5dad51169a42e0c77cb5f41d5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:18:53 +0100 Subject: [PATCH 314/503] * docs/grub.texi (Security): Menu entries are unrestricted by default, not restricted to superusers as I had previously thought. Reword to account for this. --- ChangeLog | 6 ++++++ docs/grub.texi | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c28f77bc8..ce24487d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-08 Colin Watson + + * docs/grub.texi (Security): Menu entries are unrestricted by + default, not restricted to superusers as I had previously thought. + Reword to account for this. + 2010-06-07 Colin Watson * kern/emu/misc.c (device_mapper_null_log): New function. diff --git a/docs/grub.texi b/docs/grub.texi index ffc6b8fe2..1c23460ea 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1946,11 +1946,14 @@ sets the password hashed using the Password-Based Key Derivation Function In order to enable authentication support, the @samp{superusers} environment variable must be set to a list of usernames, separated by any of spaces, commas, semicolons, pipes, or ampersands. Superusers are permitted to use -the GRUB command line, edit menu entries, and execute any menu entry. +the GRUB command line, edit menu entries, and execute any menu entry. If +@samp{superusers} is set, then use of the command line is automatically +restricted to superusers. Other users may be given access to specific menu entries by giving a list of -usernames (as above) using the @kbd{--users} option to the @samp{menuentry} -command (@pxref{menuentry}). +usernames (as above) using the @option{--users} option to the +@samp{menuentry} command (@pxref{menuentry}). If the @option{--users} +option is not used for a menu entry, then that entry is unrestricted. Putting this together, a typical @file{grub.cfg} fragment might look like this: @@ -1961,12 +1964,17 @@ set superusers="root" password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring password user1 insecure -menuentry "Superusers only" @{ +menuentry "May be run by any user" @{ set root=(hd0,1) linux /vmlinuz @} -menuentry "May be run by user1" --users user1 @{ +menuentry "Superusers only" --users "" @{ + set root=(hd0,1) + linux /vmlinuz single +@} + +menuentry "May be run by user1 or a superuser" --users user1 @{ set root=(hd0,2) chainloader +1 @} From d39f3dec5fefecbc83d64106d39b0a12281efaad Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:29:25 +0100 Subject: [PATCH 315/503] * docs/grub.texi (History): Expand to cover GRUB 2. (Serial terminal): Refer to `terminal_input' and `terminal_output' commands, not `terminal'. (serial): Likewise. (terminal_input): New section. (terminal_output): New section. (uppermem): New section (stub). (Obtaining and Building GRUB): Refer to Bazaar, not Subversion. --- ChangeLog | 11 ++++++++ docs/grub.texi | 74 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce24487d3..15be02a51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-08 Colin Watson + + * docs/grub.texi (History): Expand to cover GRUB 2. + (Serial terminal): Refer to `terminal_input' and `terminal_output' + commands, not `terminal'. + (serial): Likewise. + (terminal_input): New section. + (terminal_output): New section. + (uppermem): New section (stub). + (Obtaining and Building GRUB): Refer to Bazaar, not Subversion. + 2010-06-08 Colin Watson * docs/grub.texi (Security): Menu entries are unrestricted by diff --git a/docs/grub.texi b/docs/grub.texi index 1c23460ea..ac3bc2f90 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -174,6 +174,22 @@ official GNU package, and opened its development by making the latest sources available via anonymous CVS. @xref{Obtaining and Building GRUB}, for more information. +Over the next few years, GRUB was extended to meet many needs, but it +quickly became clear that its design was not keeping up with the extensions +being made to it, and we reached the point where it was very difficult to +make any further changes without breaking existing features. Around 2002, +Yoshinori K. Okuji started work on PUPA (Preliminary Universal Programming +Architecture for GNU GRUB), aiming to rewrite the core of GRUB to make it +cleaner, safer, more robust, and more powerful. PUPA was eventually renamed +to GRUB 2, and the original version of GRUB was renamed to GRUB Legacy. +Small amounts of maintenance continued to be done on GRUB Legacy, but the +last release (0.97) was made in 2005 and at the time of writing it seems +unlikely that there will be another. + +By around 2007, GNU/Linux distributions started to use GRUB 2 to limited +extents, and by the end of 2009 multiple major distributions were installing +it by default. + @node Features @section GRUB features @@ -1078,7 +1094,8 @@ 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 +The commands @command{terminal_input} (@pxref{terminal_input}) and +@command{terminal_output} (@pxref{terminal_output} choose 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 @@ -1421,6 +1438,8 @@ Commands usable anywhere in the menu and in the command-line. @menu * serial:: Set up a serial device +* terminal_input:: Manage input terminals +* terminal_output:: Manage output terminals * terminfo:: Define terminal type @end menu @@ -1440,13 +1459,52 @@ bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd}, @samp{even} and defaults to @samp{no}. The serial port is not used as a communication channel unless the -@command{terminal} command is used (@pxref{terminal}). +@command{terminal_input} or @command{terminal_output} command is used +(@pxref{terminal_input}, @pxref{terminal_output}). This command is only available if GRUB is compiled with serial support. See also @ref{Serial terminal}. @end deffn +@node terminal_input +@subsection terminal_input + +@deffn Command terminal_input [@option{--append}|@option{--remove}] @ + [terminal1] [terminal2] @dots{} +List or select an input terminal. + +With no arguments, list the active and available input terminals. + +With @option{--append}, add the named terminals to the list of active input +terminals; any of these may be used to provide input to GRUB. + +With @option{--remove}, remove the named terminals from the active list. + +With no options but a list of terminal names, make only the listed terminal +names active. +@end deffn + + +@node terminal_output +@subsection terminal_output + +@deffn Command terminal_output [@option{--append}|@option{--remove}] @ + [terminal1] [terminal2] @dots{} +List or select an output terminal. + +With no arguments, list the active and available output terminals. + +With @option{--append}, add the named terminals to the list of active output +terminals; all of these will receive output from GRUB. + +With @option{--remove}, remove the named terminals from the active list. + +With no options but a list of terminal names, make only the listed terminal +names active. +@end deffn + + @node terminfo @subsection terminfo @@ -1499,6 +1557,7 @@ you forget a command, you can run the command @command{help} * search:: Search devices by file, label, or UUID * set:: Set an environment variable * unset:: Unset an environment variable +* uppermem:: Set the upper memory size @end menu @@ -1921,6 +1980,12 @@ Unset the environment variable @var{envvar}. @end deffn +@node uppermem +@subsection uppermem + +This command is not yet implemented for GRUB 2, although it is planned. + + @node Security @chapter Authentication and authorisation @@ -2190,8 +2255,9 @@ just do: @end group @end example -Also, the latest version is available from the SVN. See -@uref{http://savannah.gnu.org/svn/?group=grub} for more information. +Also, the latest version is available using Bazaar. See +@uref{http://www.gnu.org/software/grub/grub-download.en.html} for more +information. @node Reporting bugs @appendix Reporting bugs From 50e532ca1a421581c6ea63f77a9cd2a5e8c8548a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:37:16 +0100 Subject: [PATCH 316/503] * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and grub_script.yy.h. --- .bzrignore | 4 ++++ ChangeLog | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.bzrignore b/.bzrignore index 46e8637b6..aa9c4ff84 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3,6 +3,8 @@ 30_os-prober 40_custom aclocal.m4 +ascii.bitmaps +ascii.h autom4te.cache build_env.mk .bzrignore @@ -48,6 +50,8 @@ grub_script_check_init.c grub_script_check_init.h grub_script.tab.c grub_script.tab.h +grub_script.yy.c +grub_script.yy.h grub-set-default grub-setup grub_setup_init.c diff --git a/ChangeLog b/ChangeLog index 15be02a51..e9570905e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-08 Colin Watson + + * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and + grub_script.yy.h. + 2010-06-08 Colin Watson * docs/grub.texi (History): Expand to cover GRUB 2. From f4d095d77d9d87a1275de19411656ff8cfe69b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:09:34 +0200 Subject: [PATCH 317/503] Add . to the directories searched for unifont. --- ChangeLog | 4 ++++ configure.ac | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9570905e..b48b79819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-08 Grégoire Sutre + + * configure.ac: Add `.' to the directories searched for unifont. + 2010-06-08 Colin Watson * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and diff --git a/configure.ac b/configure.ac index 31b179d46..97c493e27 100644 --- a/configure.ac +++ b/configure.ac @@ -179,11 +179,13 @@ if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) fi -for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do - if test -e $file ; then - AC_SUBST([FONT_SOURCE], [$file]) - break - fi +for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do + for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont; do + if test -f "$dir/unifont.$ext"; then + AC_SUBST([FONT_SOURCE], [$dir/unifont.$ext]) + break 2 + fi + done done AC_PROG_INSTALL From e8a6f3b6a5f07e8a63788e33866fa99ed8737297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:23:30 +0200 Subject: [PATCH 318/503] Use absolute offsets for start of embedding area. --- ChangeLog | 5 +++++ util/i386/pc/grub-setup.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b48b79819..45637ac17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-08 Grégoire Sutre + + * util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of + embedding area. Use <= instead of == when checking for non-emptiness. + 2010-06-08 Grégoire Sutre * configure.ac: Add `.' to the directories searched for unifont. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 6e6b2e878..08a76f65c 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -126,8 +126,8 @@ setup (const char *dir, /* There's always an embed region, and it starts right after the MBR. */ embed_region.start = 1; - if (embed_region.end > p->start) - embed_region.end = p->start; + if (embed_region.end > grub_partition_get_start (p)) + embed_region.end = grub_partition_get_start (p); return 0; } @@ -147,8 +147,8 @@ setup (const char *dir, /* 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; + embed_region.start = grub_partition_get_start (p); + embed_region.end = grub_partition_get_start (p) + grub_partition_get_len (p); return 1; } @@ -361,7 +361,7 @@ setup (const char *dir, else grub_util_error (_("No DOS-style partitions found")); - if (embed_region.end == embed_region.start) + if (embed_region.end <= embed_region.start) { if (! strcmp (dest_partmap, "msdos")) grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!")); From 0ea7c4f93cdacfd650dfba43ee6e410a2414aca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:52:42 +0200 Subject: [PATCH 319/503] Make --version uniform and avoid hard-coded program name. --- ChangeLog | 19 +++++++++++++++++++ util/grub-install.in | 10 ++++++---- util/grub-mkconfig.in | 13 ++++++++----- util/grub-mkimage.c | 2 +- util/grub-mkrescue.in | 8 +++++--- util/grub-reboot.in | 8 ++++++-- util/grub-set-default.in | 8 ++++++-- util/i386/efi/grub-install.in | 10 ++++++---- util/i386/pc/grub-setup.c | 2 +- util/ieee1275/grub-install.in | 10 ++++++---- util/powerpc/ieee1275/grub-mkrescue.in | 8 +++++--- util/sparc64/ieee1275/grub-setup.c | 2 +- 12 files changed, 70 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45637ac17..9bbeae6c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-06-08 Grégoire Sutre + + Make --version uniform and avoid hard-coded program name. + + * util/grub-mkimage.c (main): Use `program_name' instead of + hard-coded string. + * util/i386/pc/grub-setup.c (main): Likewise. + * util/sparc64/ieee1275/grub-setup.c (parse_options): Likewise. + * util/grub-install.in: Save the basename of $0 in $self, and use the + latter in informational messages. Use the same format for --version + as the binary programs. + * util/grub-mkconfig.in: Likewise. + * util/grub-mkrescue.in: Likewise. + * util/grub-reboot.in: Likewise. + * util/grub-set-default.in: Likewise. + * util/i386/efi/grub-install.in: Likewise. + * util/ieee1275/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. + 2010-06-08 Grégoire Sutre * util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of diff --git a/util/grub-install.in b/util/grub-install.in index 0db216fd5..1e7fc1f2e 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -34,6 +34,8 @@ font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` localedir=@datadir@/locale +self=`basename $0` + grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` @@ -61,7 +63,7 @@ fi # Print the usage. usage () { cat <. @@ -108,7 +110,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 0095e1ce8..d916459d6 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -23,7 +23,8 @@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ libdir=@libdir@ sysconfdir=@sysconfdir@ -package_version=@PACKAGE_VERSION@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ host_os=@host_os@ datarootdir=@datarootdir@ datadir=@datadir@ @@ -31,6 +32,8 @@ pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` grub_cfg="" grub_mkconfig_dir=${sysconfdir}/grub.d +self=`basename $0` + grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` @@ -38,7 +41,7 @@ grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` # Print the usage. usage () { cat <&2 + echo "$self: You must run this as root" >&2 exit 1 fi fi @@ -284,7 +287,7 @@ cat << EOF # # DO NOT EDIT THIS FILE # -# It is automatically generated by $0 using templates +# It is automatically generated by $self using templates # from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub # EOF diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 4e39450df..7b03c2fd0 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1307,7 +1307,7 @@ main (int argc, char *argv[]) break; case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 99b10de7b..61b0c94f7 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -30,6 +30,8 @@ target_cpu=@target_cpu@ native_platform=@platform@ pkglib_DATA="@pkglib_DATA@" +self=`basename $0` + multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu @@ -44,7 +46,7 @@ grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Print the usage. usage () { cat <. EOF @@ -67,7 +69,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/grub-reboot.in b/util/grub-reboot.in index 20f2b10bc..2c49f5e13 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -22,6 +22,10 @@ transform="@program_transform_name@" prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ + +self=`basename $0` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= @@ -30,7 +34,7 @@ rootdir= # Print the usage. usage () { cat <. @@ -78,7 +80,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; @@ -219,7 +221,7 @@ $grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 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 "fix it and re-run the script \`$self'." echo cat $device_map diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 08a76f65c..ef0f5a990 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -702,7 +702,7 @@ main (int argc, char *argv[]) break; case 'V': - printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 4d00cc217..72135213d 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -34,6 +34,8 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` +self=`basename $0` + grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` @@ -53,7 +55,7 @@ nvsetenv=`which nvsetenv` # Print the usage. usage () { cat <. EOF @@ -61,7 +63,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 8a2d30ba1..93e135eb3 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -503,7 +503,7 @@ parse_options (struct grub_setup_info *gp, int argc, char *argv[]) break; case 'V': - printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': From 9146024736865ce501bd750cb1b7a0b286db48e0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 9 Jun 2010 20:43:25 +0200 Subject: [PATCH 320/503] 2010-06-09 Robert Millan * util/grub.d/10_linux.in: Prefer compressed images over non-compressed ones, when both are available. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9bbeae6c2..6158ef4b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-09 Robert Millan + + * util/grub.d/10_linux.in: Prefer compressed images over non-compressed + ones, when both are available. + 2010-06-08 Grégoire Sutre Make --version uniform and avoid hard-coded program name. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 802d59f51..416ab6ed6 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -97,7 +97,7 @@ EOF EOF } -list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do +list=`for i in /boot/vmlinu[zx]-* /vmlinu[zx]-* ; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` prepare_boot_cache= From 6289c3a71507d8b02d859aa2e59d4e4dc81eb417 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Jun 2010 22:24:12 +0200 Subject: [PATCH 321/503] * docs/grub.texi (Vendor power-on button): Add Asus EeePC 1005PE as reported by Henrique Ferreiro. --- ChangeLog | 5 +++++ docs/grub.texi | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6158ef4b3..0575e7c5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-09 Vladimir Serbinenko + + * docs/grub.texi (Vendor power-on button): Add Asus EeePC 1005PE as + reported by Henrique Ferreiro. + 2010-06-09 Robert Millan * util/grub.d/10_linux.in: Prefer compressed images over non-compressed diff --git a/docs/grub.texi b/docs/grub.texi index ac3bc2f90..9fe197da2 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1123,6 +1123,8 @@ Values known to GRUB team are: @table @key @item Dell XPS M1530 85:3 +@item Asus EeePC 1005PE +84:1 (unconfirmed) @end table To take full advantage of this function install GRUB into MBR. From 56a0d956d196be7828d0845aa225a0514c395e37 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Jun 2010 22:12:16 +0100 Subject: [PATCH 322/503] * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m when generating manual pages. * docs/man/grub-bin2h.h2m: New file. * docs/man/grub-editenv.h2m: New file. * docs/man/grub-fstest.h2m: New file. * docs/man/grub-install.h2m: New file. * docs/man/grub-macho2img.h2m: New file. * docs/man/grub-mkconfig.h2m: New file. * docs/man/grub-mkdevicemap.h2m: New file. * docs/man/grub-mkfont.h2m: New file. * docs/man/grub-mkimage.h2m: New file. * docs/man/grub-mkpasswd-pbkdf2.h2m: New file. * docs/man/grub-mkrelpath.h2m: New file. * docs/man/grub-mkrescue.h2m: New file. * docs/man/grub-ofpathname.h2m: New file. * docs/man/grub-pe2elf.h2m: New file. * docs/man/grub-probe.h2m: New file. * docs/man/grub-reboot.h2m: New file. * docs/man/grub-script-check.h2m: New file. * docs/man/grub-set-default.h2m: New file. * docs/man/grub-setup.h2m: New file. --- ChangeLog | 24 ++++++++++++++++++++++++ Makefile.in | 8 ++++---- docs/man/grub-bin2h.h2m | 2 ++ docs/man/grub-editenv.h2m | 2 ++ docs/man/grub-fstest.h2m | 2 ++ docs/man/grub-install.h2m | 2 ++ docs/man/grub-macho2img.h2m | 2 ++ docs/man/grub-mkconfig.h2m | 2 ++ docs/man/grub-mkdevicemap.h2m | 2 ++ docs/man/grub-mkfont.h2m | 2 ++ docs/man/grub-mkimage.h2m | 2 ++ docs/man/grub-mkpasswd-pbkdf2.h2m | 2 ++ docs/man/grub-mkrelpath.h2m | 2 ++ docs/man/grub-mkrescue.h2m | 2 ++ docs/man/grub-ofpathname.h2m | 2 ++ docs/man/grub-pe2elf.h2m | 2 ++ docs/man/grub-probe.h2m | 2 ++ docs/man/grub-reboot.h2m | 2 ++ docs/man/grub-script-check.h2m | 2 ++ docs/man/grub-set-default.h2m | 2 ++ docs/man/grub-setup.h2m | 2 ++ 21 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 docs/man/grub-bin2h.h2m create mode 100644 docs/man/grub-editenv.h2m create mode 100644 docs/man/grub-fstest.h2m create mode 100644 docs/man/grub-install.h2m create mode 100644 docs/man/grub-macho2img.h2m create mode 100644 docs/man/grub-mkconfig.h2m create mode 100644 docs/man/grub-mkdevicemap.h2m create mode 100644 docs/man/grub-mkfont.h2m create mode 100644 docs/man/grub-mkimage.h2m create mode 100644 docs/man/grub-mkpasswd-pbkdf2.h2m create mode 100644 docs/man/grub-mkrelpath.h2m create mode 100644 docs/man/grub-mkrescue.h2m create mode 100644 docs/man/grub-ofpathname.h2m create mode 100644 docs/man/grub-pe2elf.h2m create mode 100644 docs/man/grub-probe.h2m create mode 100644 docs/man/grub-reboot.h2m create mode 100644 docs/man/grub-script-check.h2m create mode 100644 docs/man/grub-set-default.h2m create mode 100644 docs/man/grub-setup.h2m diff --git a/ChangeLog b/ChangeLog index c4a6246ee..43cf36b32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2010-06-11 Colin Watson + + * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m + when generating manual pages. + * docs/man/grub-bin2h.h2m: New file. + * docs/man/grub-editenv.h2m: New file. + * docs/man/grub-fstest.h2m: New file. + * docs/man/grub-install.h2m: New file. + * docs/man/grub-macho2img.h2m: New file. + * docs/man/grub-mkconfig.h2m: New file. + * docs/man/grub-mkdevicemap.h2m: New file. + * docs/man/grub-mkfont.h2m: New file. + * docs/man/grub-mkimage.h2m: New file. + * docs/man/grub-mkpasswd-pbkdf2.h2m: New file. + * docs/man/grub-mkrelpath.h2m: New file. + * docs/man/grub-mkrescue.h2m: New file. + * docs/man/grub-ofpathname.h2m: New file. + * docs/man/grub-pe2elf.h2m: New file. + * docs/man/grub-probe.h2m: New file. + * docs/man/grub-reboot.h2m: New file. + * docs/man/grub-script-check.h2m: New file. + * docs/man/grub-set-default.h2m: New file. + * docs/man/grub-setup.h2m: New file. + 2010-06-10 Vladimir Serbinenko Use FOR_* macros instead of *_iterate whenever possible. diff --git a/Makefile.in b/Makefile.in index 75388e3c8..afe4beb6e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -323,26 +323,26 @@ install-local: all 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 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ done $(SHELL) $(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 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ 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 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ 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 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \ diff --git a/docs/man/grub-bin2h.h2m b/docs/man/grub-bin2h.h2m new file mode 100644 index 000000000..ef463f3d1 --- /dev/null +++ b/docs/man/grub-bin2h.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-bin2h \- convert a binary file to a C header diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m new file mode 100644 index 000000000..efbd79070 --- /dev/null +++ b/docs/man/grub-editenv.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-editenv \- edit GRUB environment block diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m new file mode 100644 index 000000000..be39429b5 --- /dev/null +++ b/docs/man/grub-fstest.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-fstest \- debug tool for GRUB filesystem drivers diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m new file mode 100644 index 000000000..65252155c --- /dev/null +++ b/docs/man/grub-install.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-install \- install GRUB to a device diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m new file mode 100644 index 000000000..412bf926a --- /dev/null +++ b/docs/man/grub-macho2img.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-macho2img \- convert Mach-O to raw image diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m new file mode 100644 index 000000000..b0d33ec61 --- /dev/null +++ b/docs/man/grub-mkconfig.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkconfig \- generate a GRUB configuration file diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m new file mode 100644 index 000000000..8ab34ac86 --- /dev/null +++ b/docs/man/grub-mkdevicemap.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkdevicemap \- generate a GRUB device map file automatically diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m new file mode 100644 index 000000000..d8580186f --- /dev/null +++ b/docs/man/grub-mkfont.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkfont \- make GRUB font files diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m new file mode 100644 index 000000000..71f270940 --- /dev/null +++ b/docs/man/grub-mkimage.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkimage \- make a bootable image of GRUB diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m new file mode 100644 index 000000000..5b2b2ef7f --- /dev/null +++ b/docs/man/grub-mkpasswd-pbkdf2.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m new file mode 100644 index 000000000..ccc0880fa --- /dev/null +++ b/docs/man/grub-mkrelpath.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkrelpath \- make a system path relative to its root diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m new file mode 100644 index 000000000..5e92e0d99 --- /dev/null +++ b/docs/man/grub-mkrescue.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkrescue \- make a GRUB rescue image diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m new file mode 100644 index 000000000..f07158cb3 --- /dev/null +++ b/docs/man/grub-ofpathname.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-ofpathname \- find OpenBOOT path for a device diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m new file mode 100644 index 000000000..3fdb88b43 --- /dev/null +++ b/docs/man/grub-pe2elf.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-pe2elf \- convert PE image to ELF diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m new file mode 100644 index 000000000..817ba8ef6 --- /dev/null +++ b/docs/man/grub-probe.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-probe \- probe device information for GRUB diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m new file mode 100644 index 000000000..957e4b797 --- /dev/null +++ b/docs/man/grub-reboot.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-reboot \- set the default boot entry for GRUB, for the next boot only diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m new file mode 100644 index 000000000..39c0a3ef6 --- /dev/null +++ b/docs/man/grub-script-check.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-script-check \- check grub.cfg for syntax errors diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m new file mode 100644 index 000000000..3ac13d7ed --- /dev/null +++ b/docs/man/grub-set-default.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-set-default \- set the default boot entry for GRUB diff --git a/docs/man/grub-setup.h2m b/docs/man/grub-setup.h2m new file mode 100644 index 000000000..e70e465a4 --- /dev/null +++ b/docs/man/grub-setup.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-setup \- set up a device to boot using GRUB From 283af07aff47fdc234e80da3fa4c5891f0ab9289 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Jun 2010 22:15:35 +0100 Subject: [PATCH 323/503] * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... (GRUB_EFI_UGA_BLT_MAX): ... this (typo fix). --- ChangeLog | 5 +++++ include/grub/efi/uga_draw.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 43cf36b32..ab9415191 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-11 Colin Watson + + * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... + (GRUB_EFI_UGA_BLT_MAX): ... this (typo fix). + 2010-06-11 Colin Watson * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h index 93504307c..a31f2672e 100644 --- a/include/grub/efi/uga_draw.h +++ b/include/grub/efi/uga_draw.h @@ -32,7 +32,7 @@ enum grub_efi_uga_blt_operation GRUB_EFI_UGA_VIDEO_TO_BLT, GRUB_EFI_UGA_BLT_TO_VIDEO, GRUB_EFI_UGA_VIDEO_TO_VIDEO, - GRUB_EFI_UGA_GLT_MAX + GRUB_EFI_UGA_BLT_MAX }; struct grub_efi_uga_pixel From ee62c427e51eb267ccc0e69823c1bb05ca75e2d6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 12 Jun 2010 12:02:38 +0100 Subject: [PATCH 324/503] * util/grub-mkrescue.in (make_image): Remove sh module, which has been merged back into normal. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ab9415191..1def7af01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-12 Colin Watson + + * util/grub-mkrescue.in (make_image): Remove sh module, which has + been merged back into normal. + 2010-06-11 Colin Watson * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 61b0c94f7..ee269d692 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -173,7 +173,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} $grub_mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ - search iso9660 configfile normal sh memdisk tar $4 + search iso9660 configfile normal memdisk tar $4 rm -rf ${memdisk_img} } From 57711df6adc0162ec00688faa809258ac0c0e91c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Jun 2010 13:20:21 +0200 Subject: [PATCH 325/503] custom.cfg support. * conf/common.rmk (grub-mkconfig_SCRIPTS): Add 41_custom. * util/grub.d/41_custom.in: New file. --- ChangeLog | 7 +++++++ conf/common.rmk | 2 +- util/grub.d/41_custom.in | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 util/grub.d/41_custom.in diff --git a/ChangeLog b/ChangeLog index 1def7af01..f148d3204 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-12 Vladimir Serbinenko + + custom.cfg support. + + * conf/common.rmk (grub-mkconfig_SCRIPTS): Add 41_custom. + * util/grub.d/41_custom.in: New file. + 2010-06-12 Colin Watson * util/grub-mkrescue.in (make_image): Remove sh module, which has diff --git a/conf/common.rmk b/conf/common.rmk index 3b9d1e5ce..bf73c2d59 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -201,7 +201,7 @@ CLEANFILES += grub-gettext_lib %: util/grub.d/%.in config.status ./config.status --file=$@:$< chmod +x $@ -grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom +grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom 41_custom ifneq (, $(host_kernel)) grub-mkconfig_SCRIPTS += 10_$(host_kernel) endif diff --git a/util/grub.d/41_custom.in b/util/grub.d/41_custom.in new file mode 100644 index 000000000..64d691c55 --- /dev/null +++ b/util/grub.d/41_custom.in @@ -0,0 +1,7 @@ +#!/bin/sh +cat < Date: Sat, 12 Jun 2010 13:44:01 +0200 Subject: [PATCH 326/503] * util/grub-mkrescue.in: Add --sort-weight arguments to xorriso. Suggested by: Thomas Schmitt. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f148d3204..9c8b21bd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-12 Vladimir Serbinenko + + * util/grub-mkrescue.in: Add --sort-weight arguments to xorriso. + Suggested by: Thomas Schmitt. + 2010-06-12 Vladimir Serbinenko custom.cfg support. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index ee269d692..1c8bd8e67 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -269,7 +269,7 @@ if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then fi # build iso image -xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} +xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} --sort-weight 0 / --sort-weight 1 /boot ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} From 25c56d29284144dfab0f01d843caede2a0315525 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Jun 2010 13:47:08 +0200 Subject: [PATCH 327/503] * util/grub-mkrescue.in: Use -graft-points instead of -pathspecs. Suggested by: Thomas Schmitt. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9c8b21bd3..798af2e7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-12 Vladimir Serbinenko + + * util/grub-mkrescue.in: Use -graft-points instead of -pathspecs. + Suggested by: Thomas Schmitt. + 2010-06-12 Vladimir Serbinenko * util/grub-mkrescue.in: Add --sort-weight arguments to xorriso. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 1c8bd8e67..4d05893ba 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -269,7 +269,7 @@ if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then fi # build iso image -xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} --sort-weight 0 / --sort-weight 1 /boot ${source} +xorriso -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} --sort-weight 0 / --sort-weight 1 /boot ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} From a60859731830306a20f2932fd352015bc83e870e Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 12 Jun 2010 13:54:35 +0200 Subject: [PATCH 328/503] * util/grub-mkrescue.in: Support --xorriso argument. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 798af2e7f..a6a06053f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-12 Thomas Schmitt + + * util/grub-mkrescue.in: Support --xorriso argument. + 2010-06-12 Vladimir Serbinenko * util/grub-mkrescue.in: Use -graft-points instead of -pathspecs. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4d05893ba..90c031882 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -42,6 +42,8 @@ rom_directory= override_dir= grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` +xorriso=xorriso + # Usage: usage # Print the usage. usage () { @@ -54,6 +56,7 @@ Make GRUB rescue image. --output=FILE save output in FILE [required] --modules=MODULES pre-load specified modules MODULES --rom-directory=DIR save rom images in DIR [optional] + --xorriso=FILE use FILE as xorriso [optional] --grub-mkimage=FILE use FILE as grub-mkimage $self generates a bootable rescue image with specified source files or directories. @@ -85,6 +88,8 @@ for option in "$@"; do ;; --grub-mkimage=*) grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --xorriso=*) + xorriso=`echo "${option}/" | sed 's/--xorriso=//'` ;; -*) echo "Unrecognized option \`$option'" 1>&2 usage @@ -269,7 +274,7 @@ if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then fi # build iso image -xorriso -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} --sort-weight 0 / --sort-weight 1 /boot ${source} +"${xorriso}" -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} --sort-weight 0 / --sort-weight 1 /boot ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} From 1c8f0f8d11bb69b18501793f8c29c62644c0460c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Mart=C3=ADn?= Date: Sat, 12 Jun 2010 14:50:07 +0200 Subject: [PATCH 329/503] * include/grub/types.h: Check for GRUB_CPU_SIZEOF_LONG when appropriate. --- ChangeLog | 4 ++++ include/grub/types.h | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6a06053f..8f85c127a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-12 Javier Martín + + * include/grub/types.h: Check for GRUB_CPU_SIZEOF_LONG when appropriate. + 2010-06-12 Thomas Schmitt * util/grub-mkrescue.in: Support --xorriso argument. diff --git a/include/grub/types.h b/include/grub/types.h index 6e9461f1d..a9e8adfd6 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -60,7 +60,7 @@ typedef signed char grub_int8_t; typedef short grub_int16_t; typedef int grub_int32_t; -#if GRUB_CPU_SIZEOF_VOID_P == 8 +#if GRUB_CPU_SIZEOF_LONG == 8 typedef long grub_int64_t; #else typedef long long grub_int64_t; @@ -69,7 +69,7 @@ typedef long long grub_int64_t; typedef unsigned char grub_uint8_t; typedef unsigned short grub_uint16_t; typedef unsigned grub_uint32_t; -#if GRUB_CPU_SIZEOF_VOID_P == 8 +#if GRUB_CPU_SIZEOF_LONG == 8 typedef unsigned long grub_uint64_t; #else typedef unsigned long long grub_uint64_t; @@ -98,7 +98,7 @@ typedef grub_uint32_t grub_size_t; typedef grub_int32_t grub_ssize_t; #endif -#if GRUB_CPU_SIZEOF_VOID_P == 8 +#if GRUB_CPU_SIZEOF_LONG == 8 # define GRUB_ULONG_MAX 18446744073709551615UL # define GRUB_LONG_MAX 9223372036854775807L # define GRUB_LONG_MIN (-9223372036854775807L - 1) From 7beac90c5f2a1b8af2e17b7922e0cdf7968046b1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 12 Jun 2010 14:33:09 +0100 Subject: [PATCH 330/503] Avoid false positives in fs.lst, partmap.lst, and video.lst due to prototype declarations. * genmk.rb (PModule::rule): Define GRUB_LST_GENERATOR when generating fs, partmap, and video lists. * include/grub/fs.h (grub_fs_register): Omit prototype if GRUB_LST_GENERATOR is defined. * include/grub/partition.h (grub_partition_map_register): Likewise. * include/grub/video.h (grub_video_register): Likewise. --- ChangeLog | 12 ++++++++++++ genmk.rb | 6 +++--- include/grub/fs.h | 2 ++ include/grub/partition.h | 2 ++ include/grub/video.h | 2 ++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8f85c127a..aababc845 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-06-12 Colin Watson + + Avoid false positives in fs.lst, partmap.lst, and video.lst due to + prototype declarations. + + * genmk.rb (PModule::rule): Define GRUB_LST_GENERATOR when + generating fs, partmap, and video lists. + * include/grub/fs.h (grub_fs_register): Omit prototype if + GRUB_LST_GENERATOR is defined. + * include/grub/partition.h (grub_partition_map_register): Likewise. + * include/grub/video.h (grub_video_register): Likewise. + 2010-06-12 Javier Martín * include/grub/types.h: Check for GRUB_CPU_SIZEOF_LONG when appropriate. diff --git a/genmk.rb b/genmk.rb index e62dbd4f6..01b969ecf 100644 --- a/genmk.rb +++ b/genmk.rb @@ -228,7 +228,7 @@ VIDEOFILES += #{video} #{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh set -e; \ - $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ | sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) #{parttool}: #{src} $(#{src}_DEPENDENCIES) genparttoollist.sh @@ -238,7 +238,7 @@ VIDEOFILES += #{video} #{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh set -e; \ - $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ | sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) #{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh @@ -253,7 +253,7 @@ VIDEOFILES += #{video} #{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh set -e; \ - $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ | sh $(srcdir)/genvideolist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) " diff --git a/include/grub/fs.h b/include/grub/fs.h index 3368eb553..994eb8080 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -91,11 +91,13 @@ typedef int (*grub_fs_autoload_hook_t) (void); extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook); extern grub_fs_t EXPORT_VAR (grub_fs_list); +#ifndef GRUB_LST_GENERATOR static inline void grub_fs_register (grub_fs_t fs) { grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); } +#endif static inline void grub_fs_unregister (grub_fs_t fs) diff --git a/include/grub/partition.h b/include/grub/partition.h index 722c7b3e0..a23e94e07 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -77,12 +77,14 @@ char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list); +#ifndef GRUB_LST_GENERATOR static inline void grub_partition_map_register (grub_partition_map_t partmap) { grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list), GRUB_AS_LIST (partmap)); } +#endif static inline void grub_partition_map_unregister (grub_partition_map_t partmap) diff --git a/include/grub/video.h b/include/grub/video.h index 0a8fe1efe..faf2973ef 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -264,6 +264,7 @@ typedef struct grub_video_adapter *grub_video_adapter_t; extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list); +#ifndef GRUB_LST_GENERATOR /* Register video driver. */ static inline void grub_video_register (grub_video_adapter_t adapter) @@ -271,6 +272,7 @@ grub_video_register (grub_video_adapter_t adapter) grub_list_push (GRUB_AS_LIST_P (&grub_video_adapter_list), GRUB_AS_LIST (adapter)); } +#endif /* Unregister video driver. */ static inline void From ce08a9fb28c3f66accaf8ddc8c48e5052b484582 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 12 Jun 2010 16:03:34 +0200 Subject: [PATCH 331/503] * util/grub-mkrescue.in: Pass unrecognized options to xorriso. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 10 ++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index aababc845..34823d8b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-12 Thomas Schmitt + + * util/grub-mkrescue.in: Pass unrecognized options to xorriso. + 2010-06-12 Colin Watson Avoid false positives in fs.lst, partmap.lst, and video.lst due to diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 90c031882..f8445a1e3 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -59,9 +59,12 @@ Make GRUB rescue image. --xorriso=FILE use FILE as xorriso [optional] --grub-mkimage=FILE use FILE as grub-mkimage -$self generates a bootable rescue image with specified source files or directories. +$self generates a bootable rescue image with specified source files, source +directories, or mkisofs options listed by: xorriso -as mkisofs -help +Option -- switches to native xorriso command mode. or directories. Report bugs to . +Mail xorriso support requests to . EOF } @@ -90,11 +93,6 @@ for option in "$@"; do grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; --xorriso=*) xorriso=`echo "${option}/" | sed 's/--xorriso=//'` ;; - -*) - echo "Unrecognized option \`$option'" 1>&2 - usage - exit 1 - ;; *) source="${source} ${option}" ;; esac From 601c84fd16bff48c8fdcd02b0e4381025ff110b5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 12 Jun 2010 15:06:53 +0100 Subject: [PATCH 332/503] * util/grub-mkconfig.in: Capitalise and export GRUB_PREFIX. * util/grub.d/00_header.in: Use GRUB_PREFIX rather than computing it again. * util/grub.d/10_linux.in (linux_entry): Load all video drivers, which may be needed to allow the loader to program modes for the kernel. --- util/grub-mkconfig.in | 15 ++++++++------- util/grub.d/00_header.in | 5 ++--- util/grub.d/10_linux.in | 10 ++++++++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index d916459d6..836bd6318 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -92,11 +92,11 @@ 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}` + GRUB_PREFIX=`echo /grub | sed ${transform}` ;; *) # Use /boot/grub by default. - grub_prefix=`echo /boot/grub | sed ${transform}` + GRUB_PREFIX=`echo /boot/grub | sed ${transform}` ;; esac @@ -137,9 +137,9 @@ else exit 1 fi -mkdir -p ${grub_prefix} +mkdir -p ${GRUB_PREFIX} -if test -e ${grub_prefix}/device.map ; then : ; else +if test -e ${GRUB_PREFIX}/device.map ; then : ; else ${grub_mkdevicemap} fi @@ -174,7 +174,7 @@ fi for x in ${GRUB_TERMINAL_OUTPUT}; do if [ "x${x}" = "xgfxterm" ]; then # If this platform supports gfxterm, try to use it. - if ! test -e ${grub_prefix}/gfxterm.mod ; then + if ! test -e ${GRUB_PREFIX}/gfxterm.mod ; then if [ "x$termoutdefault" != "x1" ]; then echo "gfxterm isn't available on your platform" >&2 ; exit 1 fi @@ -183,7 +183,7 @@ for x in ${GRUB_TERMINAL_OUTPUT}; do fi # FIXME: this should do something smarter than just loading first # video backend. - GRUB_VIDEO_BACKEND=$(head -n 1 ${grub_prefix}/video.lst || true) + GRUB_VIDEO_BACKEND=$(head -n 1 ${GRUB_PREFIX}/video.lst || true) if [ -z "${GRUB_VIDEO_BACKEND}" ] ; then if [ "x$termoutdefault" != "x1" ]; then echo "No suitable backend could be found for gfxterm." >&2 ; exit 1 @@ -242,7 +242,8 @@ export GRUB_DEVICE \ GRUB_FS \ GRUB_FONT_PATH \ GRUB_PRELOAD_MODULES \ - GRUB_VIDEO_BACKEND + GRUB_VIDEO_BACKEND \ + GRUB_PREFIX # These are optional, user-defined variables. export GRUB_DEFAULT \ diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 791840a60..76e0bc32d 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -21,8 +21,7 @@ transform="@program_transform_name@" prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -grub_prefix=`echo /boot/grub | sed ${transform}` -locale_dir=`echo /boot/grub/locale | sed ${transform}` +locale_dir=`echo ${GRUB_PREFIX}/locale | sed ${transform}` grub_lang=`echo $LANG | cut -d _ -f 1` . ${libdir}/grub/grub-mkconfig_lib @@ -89,7 +88,7 @@ for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do done if [ "x$serial" = x1 ]; then - if ! test -e ${grub_prefix}/serial.mod ; then + if ! test -e ${GRUB_PREFIX}/serial.mod ; then echo "Serial terminal not available on this platform." >&2 ; exit 1 fi diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 416ab6ed6..b2cff628d 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -78,6 +78,16 @@ EOF EOF fi + # Load video drivers, which may be needed to allow the loader to program + # modes for the kernel. + # TODO: Other kernels may need the same mode programming, especially on + # EFI. Should we move this somewhere more generic? + for module in $(cat ${GRUB_PREFIX}/video.lst); do + cat << EOF + insmod $module +EOF + done + if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi From c16be99ba318a111592c63e6419215a4d16965df Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 12 Jun 2010 15:09:38 +0100 Subject: [PATCH 333/503] * .bzrignore: Ignore 41_custom. --- .bzrignore | 1 + ChangeLog | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.bzrignore b/.bzrignore index aa9c4ff84..c124c9280 100644 --- a/.bzrignore +++ b/.bzrignore @@ -2,6 +2,7 @@ 10_* 30_os-prober 40_custom +41_custom aclocal.m4 ascii.bitmaps ascii.h diff --git a/ChangeLog b/ChangeLog index 34823d8b8..7a564fb14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-12 Colin Watson + + * .bzrignore: Ignore 41_custom. + 2010-06-12 Thomas Schmitt * util/grub-mkrescue.in: Pass unrecognized options to xorriso. From d49703d1517149134d8ce6a259d6c8bfb4e0b9d3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Jun 2010 17:38:48 +0200 Subject: [PATCH 334/503] Add priorities support --- include/grub/video.h | 21 ++++++++++++++++++--- video/efi_gop.c | 2 ++ video/efi_uga.c | 2 ++ video/emu/sdl.c | 3 +++ video/i386/pc/vbe.c | 2 ++ video/i386/pc/vga.c | 2 ++ video/ieee1275.c | 2 ++ video/sm712.c | 2 ++ 8 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/grub/video.h b/include/grub/video.h index faf2973ef..03de1c27b 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -183,9 +183,19 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_EFI_UGA, GRUB_VIDEO_DRIVER_EFI_GOP, GRUB_VIDEO_DRIVER_SM712, - GRUB_VIDEO_DRIVER_VGA + GRUB_VIDEO_DRIVER_VGA, + GRUB_VIDEO_DRIVER_SDL } grub_video_driver_id_t; +typedef enum grub_video_adapter_prio + { + GRUB_VIDEO_ADAPTER_PRIO_FALLBACK = 60, + GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE_DIRTY = 70, + GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE = 80, + GRUB_VIDEO_ADAPTER_PRIO_NATIVE = 100 + } grub_video_adapter_prio_t; + + struct grub_video_adapter { /* The next video adapter. */ @@ -195,6 +205,8 @@ struct grub_video_adapter const char *name; grub_video_driver_id_t id; + grub_video_adapter_prio_t prio; + /* Initialize the video adapter. */ grub_err_t (*init) (void); @@ -269,8 +281,11 @@ extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list); static inline void grub_video_register (grub_video_adapter_t adapter) { - grub_list_push (GRUB_AS_LIST_P (&grub_video_adapter_list), - GRUB_AS_LIST (adapter)); + grub_video_adapter_t *p; + for (p = &grub_video_adapter_list; *p && (*p)->prio > adapter->prio; + p = &((*p)->next)); + adapter->next = *p; + *p = adapter; } #endif diff --git a/video/efi_gop.c b/video/efi_gop.c index 86a2881f8..4e79b8521 100644 --- a/video/efi_gop.c +++ b/video/efi_gop.c @@ -355,6 +355,8 @@ static struct grub_video_adapter grub_video_gop_adapter = .name = "EFI GOP driver", .id = GRUB_VIDEO_DRIVER_EFI_GOP, + .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, + .init = grub_video_gop_init, .fini = grub_video_gop_fini, .setup = grub_video_gop_setup, diff --git a/video/efi_uga.c b/video/efi_uga.c index eb4e6b42e..6352d4342 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -302,6 +302,8 @@ static struct grub_video_adapter grub_video_uga_adapter = .name = "EFI UGA driver", .id = GRUB_VIDEO_DRIVER_EFI_UGA, + .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE_DIRTY, + .init = grub_video_uga_init, .fini = grub_video_uga_fini, .setup = grub_video_uga_setup, diff --git a/video/emu/sdl.c b/video/emu/sdl.c index d261db6b0..d66b8b0c0 100644 --- a/video/emu/sdl.c +++ b/video/emu/sdl.c @@ -200,6 +200,9 @@ grub_video_sdl_set_active_render_target (struct grub_video_render_target *target static struct grub_video_adapter grub_video_sdl_adapter = { .name = "SDL Video Driver", + .id = GRUB_VIDEO_DRIVER_SDL, + + .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, .init = grub_video_sdl_init, .fini = grub_video_sdl_fini, diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index 72b8f1831..0cc9f8000 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -783,6 +783,8 @@ static struct grub_video_adapter grub_video_vbe_adapter = .name = "VESA BIOS Extension Video Driver", .id = GRUB_VIDEO_DRIVER_VBE, + .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, + .init = grub_video_vbe_init, .fini = grub_video_vbe_fini, .setup = grub_video_vbe_setup, diff --git a/video/i386/pc/vga.c b/video/i386/pc/vga.c index 222a71272..a4fd44ecd 100644 --- a/video/i386/pc/vga.c +++ b/video/i386/pc/vga.c @@ -375,6 +375,8 @@ static struct grub_video_adapter grub_video_vga_adapter = .name = "VGA Video Driver", .id = GRUB_VIDEO_DRIVER_VGA, + .prio = GRUB_VIDEO_ADAPTER_PRIO_FALLBACK, + .init = grub_video_vga_init, .fini = grub_video_vga_fini, .setup = grub_video_vga_setup, diff --git a/video/ieee1275.c b/video/ieee1275.c index 5c6bc1594..9c9477c2b 100644 --- a/video/ieee1275.c +++ b/video/ieee1275.c @@ -254,6 +254,8 @@ static struct grub_video_adapter grub_video_ieee1275_adapter = { .name = "IEEE1275 video driver", + .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, + .init = grub_video_ieee1275_init, .fini = grub_video_ieee1275_fini, .setup = grub_video_ieee1275_setup, diff --git a/video/sm712.c b/video/sm712.c index 33861beef..98ce523c9 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -193,6 +193,8 @@ static struct grub_video_adapter grub_video_sm712_adapter = .name = "SM712 Video Driver", .id = GRUB_VIDEO_DRIVER_SM712, + .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, + .init = grub_video_sm712_video_init, .fini = grub_video_sm712_video_fini, .setup = grub_video_sm712_setup, From fcb2d0901143232e084878bbf97fb941a2f20052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sun, 13 Jun 2010 02:36:39 +0200 Subject: [PATCH 335/503] New partition naming style in grub-probe for Linux and NetBSD. --- ChangeLog | 6 ++++++ kern/emu/hostdisk.c | 30 +++++++++++++----------------- util/grub-install.in | 4 ++-- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 15856dc57..766a5053f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-13 Grégoire Sutre + + * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Use the + new partition naming style. + * util/grub-install.in: Adapt sed subtitutions in grub-probe calls. + 2010-06-12 BVK Chaitanya Add "-o grub.iso" like cmdline options support. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 47389195c..bc37e9949 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -992,6 +992,11 @@ grub_util_biosdisk_fini (void) grub_disk_dev_unregister (&grub_util_biosdisk_dev); } +/* + * Note: we do not use the new partition naming scheme as dos_part does not + * necessarily correspond to an msdos partition. See e.g. the FreeBSD code + * in function grub_util_biosdisk_get_grub_dev. + */ static char * make_device_name (int drive, int dos_part, int bsd_part) { @@ -1400,11 +1405,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) For NetBSD, proceed as for Linux, except that the start sector is obtained from the disk label. */ { - char *name; + char *name, *partname; grub_disk_t disk; grub_disk_addr_t start; - int dos_part = -1; - int bsd_part = -1; auto int find_partition (grub_disk_t dsk, const grub_partition_t partition); @@ -1419,17 +1422,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (start == part_start) { - if (partition->parent) - { - dos_part = partition->parent->number; - bsd_part = partition->number; - } - else - { - dos_part = partition->number; - bsd_part = -1; - } - + partname = grub_partition_get_name (partition); return 1; } @@ -1465,6 +1458,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (! disk) return 0; + partname = NULL; grub_partition_iterate (disk, find_partition); if (grub_errno != GRUB_ERR_NONE) { @@ -1472,7 +1466,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - if (dos_part < 0) + if (partname == NULL) { grub_disk_close (disk); grub_error (GRUB_ERR_BAD_DEVICE, @@ -1480,7 +1474,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - return make_device_name (drive, dos_part, bsd_part); + name = grub_xasprintf ("%s,%s", disk->name, partname); + free (partname); + return name; } #elif defined(__GNU__) @@ -1525,7 +1521,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) for (p = os_dev + 5; *p; ++p) if (grub_isdigit(*p)) { - p = strchr (p, 's'); + p = strchr (p, 's'); /* msdos or apple (or ... ?) partition map */ if (p) { p++; diff --git a/util/grub-install.in b/util/grub-install.in index e580ac819..c7e087dd0 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -356,12 +356,12 @@ if [ "x${devabstraction_module}" = "x" ] ; then else install_drive="`$grub_probe --target=drive --device ${install_device}`" || exit 1 fi - install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`" + install_drive="`echo ${install_drive} | sed -e s/,[a-z0-9,]*//g`" fi grub_drive="`$grub_probe --target=drive --device ${grub_device}`" || exit 1 # Strip partition number - grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*[a-z]*//g`" + grub_drive="`echo ${grub_drive} | sed -e s/,[a-z0-9,]*//g`" if [ "$disk_module" = ata ] ; then # generic method (used on coreboot and ata mod) uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`" From b5309cc1b2c6c7a45911134f341c81534819fec4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 13 Jun 2010 13:17:23 +0100 Subject: [PATCH 336/503] * docs/grub.texi (Commands): Document reduced command set in rescue mode. (cpuid): New section. --- ChangeLog | 6 ++++++ docs/grub.texi | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ChangeLog b/ChangeLog index 766a5053f..9ca80ac6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-13 Colin Watson + + * docs/grub.texi (Commands): Document reduced command set in rescue + mode. + (cpuid): New section. + 2010-06-13 Grégoire Sutre * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Use the diff --git a/docs/grub.texi b/docs/grub.texi index 9fe197da2..714145807 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1378,6 +1378,10 @@ 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. +In rescue mode, only the @command{insmod} (@pxref{insmod}), @command{ls} +(@pxref{ls}), @command{set} (@pxref{set}), and @command{unset} +(@pxref{unset}) commands are normally available. + @menu * Menu-specific commands:: * General commands:: @@ -1538,6 +1542,7 @@ you forget a command, you can run the command @command{help} * chainloader:: Chain-load another boot loader * cmp:: Compare two files * configfile:: Load a configuration file +* cpuid:: Check for CPU features * crc:: Calculate CRC32 checksums * date:: Display or set current date and time * drivemap:: Map a drive to another @@ -1659,6 +1664,20 @@ Load @var{file} as a configuration file. @end deffn +@node cpuid +@subsection cpuid + +@deffn Command cpuid [-l] +Check for CPU features. This command is only available on x86 systems. + +With the @option{-l} option, return true if the CPU supports long mode +(64-bit). + +If invoked without options, this command currently behaves as if it had been +invoked with @option{-l}. This may change in the future. +@end deffn + + @node crc @subsection crc From 41160e2e6f529ef96cfbfb0f1961753439d285f2 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 14 Jun 2010 15:08:02 +0100 Subject: [PATCH 337/503] * docs/man/grub-emu.h2m: New file. --- ChangeLog | 4 ++++ docs/man/grub-emu.h2m | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 docs/man/grub-emu.h2m diff --git a/ChangeLog b/ChangeLog index 9ca80ac6f..6d8133fbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-14 Colin Watson + + * docs/man/grub-emu.h2m: New file. + 2010-06-13 Colin Watson * docs/grub.texi (Commands): Document reduced command set in rescue diff --git a/docs/man/grub-emu.h2m b/docs/man/grub-emu.h2m new file mode 100644 index 000000000..09a1f88c1 --- /dev/null +++ b/docs/man/grub-emu.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-emu \- GRUB emulator From 8d70754eed95ce1bdf10a21dc10f6400153f0835 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 14 Jun 2010 15:34:47 +0100 Subject: [PATCH 338/503] * util/grub-mkconfig.in: Remove vestige of old argument parsing that left this script non-functional. --- ChangeLog | 5 +++++ util/grub-mkconfig.in | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d8133fbf..6833765ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-14 Colin Watson + + * util/grub-mkconfig.in: Remove vestige of old argument parsing that + left this script non-functional. + 2010-06-14 Colin Watson * docs/man/grub-emu.h2m: New file. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 0c17d07f6..c9a6df417 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -92,11 +92,6 @@ do ;; esac done -if $next_grub_cfg; then - echo "Missing argument to \`-o'" 1>&2 - usage - exit 1 -fi . ${libdir}/grub/grub-mkconfig_lib From 662e24d5f39d50a163a27133e6d3ee360eb0c94f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 14 Jun 2010 20:27:25 +0200 Subject: [PATCH 339/503] Remove leftover commands/handler.c in POTFILES. --- ChangeLog | 4 ++++ po/POTFILES | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6833765ac..5dff53209 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-14 Grégoire Sutre + + * po/POTFILES: Remove leftover commands/handler.c. + 2010-06-14 Colin Watson * util/grub-mkconfig.in: Remove vestige of old argument parsing that diff --git a/po/POTFILES b/po/POTFILES index d2c579edb..cfa1e33cb 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -12,7 +12,6 @@ commands/efi/fixvideo.c commands/efi/loadbios.c commands/gptsync.c commands/halt.c -commands/handler.c commands/hdparm.c commands/help.c commands/hexdump.c From 5591324fc6707df39d8dd87f9e654ca016bcd784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 14 Jun 2010 21:26:48 +0200 Subject: [PATCH 340/503] Fix help2man failure with program name transformation. --- ChangeLog | 5 +++++ Makefile.in | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5dff53209..977c33306 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-14 Grégoire Sutre + + * Makefile.in (install-local): Use $$file.h2m instead of $$dest.h2m + for manual page generation. + 2010-06-14 Grégoire Sutre * po/POTFILES: Remove leftover commands/handler.c. diff --git a/Makefile.in b/Makefile.in index afe4beb6e..b9b7f3d08 100644 --- a/Makefile.in +++ b/Makefile.in @@ -323,26 +323,26 @@ install-local: all 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 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ done $(SHELL) $(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 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ 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 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ 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 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \ From 044e2e60bed2f7f6e0495cb0b51137376179a788 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 16 Jun 2010 12:51:26 +0100 Subject: [PATCH 341/503] * util/grub-mkconfig.in: Ignore non-option arguments, for compatibility with older versions (before 2010-06-12) which did the same. In particular, this makes it easier to ship an update-grub wrapper which is compatible with that used with GRUB Legacy (Debian bug #586056). --- ChangeLog | 8 ++++++++ util/grub-mkconfig.in | 5 +---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 977c33306..88e1e43d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-16 Colin Watson + + * util/grub-mkconfig.in: Ignore non-option arguments, for + compatibility with older versions (before 2010-06-12) which did the + same. In particular, this makes it easier to ship an update-grub + wrapper which is compatible with that used with GRUB Legacy (Debian + bug #586056). + 2010-06-14 Grégoire Sutre * Makefile.in (install-local): Use $$file.h2m instead of $$dest.h2m diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index c9a6df417..726423590 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -86,10 +86,7 @@ do usage exit 1 ;; - *) - echo "Invalid parameter, $option" 1>&2 - exit 1 - ;; + # Explicitly ignore non-option arguments, for compatibility. esac done From 2164da6b25efcc410b9624c8b95aaabd7340b82e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 17 Jun 2010 12:15:37 +0100 Subject: [PATCH 342/503] Fix i386-pc prefix handling with nested partitions (Debian bug #585068). Note that the case where the core image is booted using multiboot and relocated from its original location still requires more work. * kern/i386/pc/init.c (make_install_device): If the prefix starts with "(,", fill the boot drive in between those two characters, but expect that a full partition specification including partition map names will follow. * util/i386/pc/grub-setup.c (setup): Unless an explicit prefix was specified, write a prefix without the drive name but including a full partition specification. --- ChangeLog | 15 +++++++++++++++ kern/i386/pc/init.c | 8 ++++++++ util/i386/pc/grub-setup.c | 15 +++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/ChangeLog b/ChangeLog index 88e1e43d6..e2f240f40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-06-17 Colin Watson + + Fix i386-pc prefix handling with nested partitions (Debian bug + #585068). Note that the case where the core image is booted using + multiboot and relocated from its original location still requires + more work. + + * kern/i386/pc/init.c (make_install_device): If the prefix starts + with "(,", fill the boot drive in between those two characters, but + expect that a full partition specification including partition map + names will follow. + * util/i386/pc/grub-setup.c (setup): Unless an explicit prefix was + specified, write a prefix without the drive name but including a + full partition specification. + 2010-06-16 Colin Watson * util/grub-mkconfig.in: Ignore non-option arguments, for diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index d81b1e117..8cbc757b2 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -83,6 +83,14 @@ make_install_device (void) grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix); grub_strcpy (grub_prefix, dev); } + else if (grub_prefix[1] == ',' || grub_prefix[1] == ')') + { + /* We have a prefix, but still need to fill in the boot drive. */ + grub_snprintf (dev, sizeof (dev), + "(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f', + grub_boot_drive & 0x7f, grub_prefix + 1); + grub_strcpy (grub_prefix, dev); + } return grub_prefix; } diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index f0baf1c89..454fba9fa 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -99,6 +99,7 @@ setup (const char *dir, struct grub_boot_blocklist *first_block, *block; grub_int32_t *install_dos_part, *install_bsd_part; grub_int32_t dos_part, bsd_part; + char *prefix; char *tmp_img; int i; grub_disk_addr_t first_sector; @@ -230,6 +231,8 @@ setup (const char *dir, + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART); install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); + prefix = (char *) (core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_MACHINE_PREFIX); /* Open the root device and the destination device. */ root_dev = grub_device_open (root); @@ -305,6 +308,18 @@ setup (const char *dir, dos_part = root_dev->disk->partition->number; bsd_part = -1; } + + if (prefix[0] != '(') + { + char *root_part_name, *new_prefix; + + root_part_name = + grub_partition_get_name (root_dev->disk->partition); + new_prefix = xasprintf ("(,%s)%s", root_part_name, prefix); + strcpy (prefix, new_prefix); + free (new_prefix); + free (root_part_name); + } } else dos_part = bsd_part = -1; From e4311a9f0f0e59597f4afc68673db0f0f1968967 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 17 Jun 2010 16:01:17 +0100 Subject: [PATCH 343/503] * util/grub-mkconfig.in: Stop setting GRUB_VIDEO_BACKEND. Make it available as a user override instead. Replace the gfxterm backend check with a check that ${GRUB_PREFIX}/video.lst is non-empty. * util/grub.d/00_header.in (load_video): New generated function. Call it before loading gfxterm rather than loading ${GRUB_VIDEO_BACKEND}. * util/grub.d/10_linux.in (linux_entry): Call load_video. * util/grub.d/30_os-prober.in (osx_entry): Likewise. * docs/grub.texi (Simple configuration): Document GRUB_VIDEO_BACKEND. --- docs/grub.texi | 10 ++++++++++ util/grub-mkconfig.in | 7 ++----- util/grub.d/00_header.in | 20 +++++++++++++++++++- util/grub.d/10_linux.in | 13 +++---------- util/grub.d/30_os-prober.in | 2 +- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index 9fe197da2..cea9f6a31 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -934,6 +934,16 @@ Disable the generation of recovery mode menu entries for Linux. @item GRUB_DISABLE_NETBSD_RECOVERY Disable the generation of recovery mode menu entries for NetBSD. +@item GRUB_VIDEO_BACKEND +If graphical video support is required, either because the @samp{gfxterm} +graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set, +then @command{grub-mkconfig} will normally load all available GRUB video +drivers and use the one most appropriate for your hardware. If you need to +override this for some reason, then you can set this option. + +After @command{grub-install} has been run, the available video drivers are +listed in @file{/boot/grub/video.lst}. + @item GRUB_GFXMODE Set the resolution used on the @samp{gfxterm} graphical terminal. Note that you can only use modes which your graphics card supports via VESA BIOS diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 836bd6318..6bdc166c9 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -181,10 +181,7 @@ for x in ${GRUB_TERMINAL_OUTPUT}; do GRUB_TERMINAL_OUTPUT= break; fi - # FIXME: this should do something smarter than just loading first - # video backend. - GRUB_VIDEO_BACKEND=$(head -n 1 ${GRUB_PREFIX}/video.lst || true) - if [ -z "${GRUB_VIDEO_BACKEND}" ] ; then + if [ ! -s "${GRUB_PREFIX}/video.lst" ] ; then if [ "x$termoutdefault" != "x1" ]; then echo "No suitable backend could be found for gfxterm." >&2 ; exit 1 fi @@ -242,7 +239,6 @@ export GRUB_DEVICE \ GRUB_FS \ GRUB_FONT_PATH \ GRUB_PRELOAD_MODULES \ - GRUB_VIDEO_BACKEND \ GRUB_PREFIX # These are optional, user-defined variables. @@ -265,6 +261,7 @@ export GRUB_DEFAULT \ GRUB_DISABLE_LINUX_UUID \ GRUB_DISABLE_LINUX_RECOVERY \ GRUB_DISABLE_NETBSD_RECOVERY \ + GRUB_VIDEO_BACKEND \ GRUB_GFXMODE \ GRUB_BACKGROUND \ GRUB_THEME \ diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 76e0bc32d..8040a7c9b 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -74,6 +74,24 @@ function savedefault { save_env saved_entry fi } + +function load_video { +EOF +if [ -n "${GRUB_VIDEO_BACKEND}" ]; then + cat < /dev/null \ && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-${version} 2> /dev/null; then cat << EOF @@ -78,16 +81,6 @@ EOF EOF fi - # Load video drivers, which may be needed to allow the loader to program - # modes for the kernel. - # TODO: Other kernels may need the same mode programming, especially on - # EFI. Should we move this somewhere more generic? - for module in $(cat ${GRUB_PREFIX}/video.lst); do - cat << EOF - insmod $module -EOF - done - if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index edef37e66..90e2e3d92 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -44,7 +44,7 @@ EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" cat << EOF - insmod ${GRUB_VIDEO_BACKEND} + load_video set do_resume=0 if [ /var/vm/sleepimage -nt10 / ]; then if xnu_resume /var/vm/sleepimage; then From d87ac126cd408b51546e5518ce550d6f1292fce6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 17 Jun 2010 16:18:41 +0100 Subject: [PATCH 344/503] remove temporary debugging printfs --- loader/i386/efi/linux.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 9d4db3440..4a0eae58b 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -368,8 +368,6 @@ grub_linux_boot (void) params = real_mode_mem; - grub_printf ("%d\n", __LINE__); - grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n", (unsigned) params->code32_start, (unsigned long) &(idt_desc.limit), @@ -378,8 +376,6 @@ grub_linux_boot (void) (unsigned) idt_desc.limit, (unsigned long) idt_desc.base, (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base); - grub_printf ("%d\n", __LINE__); - 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) { @@ -418,8 +414,6 @@ grub_linux_boot (void) return 0; } - grub_printf ("%d\n", __LINE__); - e820_num = 0; grub_mmap_iterate (hook); params->mmap_size = e820_num; From 094dfb699ea07d142bac35b5fecc7f4318d5a491 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 17 Jun 2010 21:20:43 +0100 Subject: [PATCH 345/503] * util/i386/pc/grub-setup.c (usage): Warn against running grub-setup directly, and recommend grub-install instead. * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. --- ChangeLog | 6 ++++++ util/i386/pc/grub-setup.c | 2 ++ util/sparc64/ieee1275/grub-setup.c | 2 ++ 3 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index e2f240f40..83023d9cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-17 Colin Watson + + * util/i386/pc/grub-setup.c (usage): Warn against running grub-setup + directly, and recommend grub-install instead. + * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. + 2010-06-17 Colin Watson Fix i386-pc prefix handling with nested partitions (Debian bug diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 454fba9fa..d04bf7619 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -608,6 +608,8 @@ Usage: %s [OPTION]... DEVICE\n\ \n\ Set up images to boot from DEVICE.\n\ DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\ +\n\ +You should not normally run %s directly. Use grub-install instead. \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\ diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 218a0e037..c20d2a046 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -407,6 +407,8 @@ Usage: %s [OPTION]... DEVICE\n\ \n\ Set up images to boot from DEVICE.\n\ DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\ +\n\ +You should not normally run %s directly. Use grub-install instead. \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\ From c88a83f64491625e0c1cfdf4faa3f574cb5d6bcc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 17 Jun 2010 21:49:50 +0100 Subject: [PATCH 346/503] * util/i386/pc/grub-setup.c (usage): Fix syntax error. * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. --- ChangeLog | 5 +++++ util/i386/pc/grub-setup.c | 2 +- util/sparc64/ieee1275/grub-setup.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83023d9cd..09a2faf12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-17 Colin Watson + + * util/i386/pc/grub-setup.c (usage): Fix syntax error. + * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. + 2010-06-17 Colin Watson * util/i386/pc/grub-setup.c (usage): Warn against running grub-setup diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index d04bf7619..a94d3e30c 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -609,7 +609,7 @@ Usage: %s [OPTION]... DEVICE\n\ Set up images to boot from DEVICE.\n\ DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\ \n\ -You should not normally run %s directly. Use grub-install instead. +You should not normally run %s directly. Use grub-install instead.\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\ diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index c20d2a046..354151257 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -408,7 +408,7 @@ Usage: %s [OPTION]... DEVICE\n\ Set up images to boot from DEVICE.\n\ DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\ \n\ -You should not normally run %s directly. Use grub-install instead. +You should not normally run %s directly. Use grub-install instead.\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\ From 7d24e434c5e0cf43c0c78731b1cc1fc33a858991 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 17 Jun 2010 21:54:04 +0100 Subject: [PATCH 347/503] * util/i386/pc/grub-setup.c (usage): Pass an extra `program_name' argument to printf. * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. --- ChangeLog | 6 ++++++ util/i386/pc/grub-setup.c | 2 +- util/sparc64/ieee1275/grub-setup.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 09a2faf12..5676f3315 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-17 Colin Watson + + * util/i386/pc/grub-setup.c (usage): Pass an extra `program_name' + argument to printf. + * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. + 2010-06-17 Colin Watson * util/i386/pc/grub-setup.c (usage): Fix syntax error. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index a94d3e30c..32f1f90e4 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -624,7 +624,7 @@ You should not normally run %s directly. Use grub-install instead.\n\ \n\ Report bugs to <%s>.\n\ "), - program_name, + program_name, program_name, DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 354151257..e53542263 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -420,7 +420,7 @@ You should not normally run %s directly. Use grub-install instead.\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ -", program_name, +", program_name, program_name, DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); From 0e489b823382755c31f3365a400761a34424c408 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Jun 2010 13:44:31 +0200 Subject: [PATCH 348/503] Remove leftover fields in sm712.c --- video/sm712.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/video/sm712.c b/video/sm712.c index 33861beef..c36a19203 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -32,10 +32,7 @@ static struct struct grub_video_mode_info mode_info; struct grub_video_render_target *render_target; - unsigned int bytes_per_scan_line; - unsigned int bytes_per_pixel; grub_uint8_t *ptr; - int index_color_mode; int mapped; grub_uint32_t base; grub_pci_device_t dev; From 6d5a33c9ac70bfe001317ba11a14427862100f1a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Jun 2010 14:17:56 +0200 Subject: [PATCH 349/503] Support >3GiB and < 16MiB of RAM in i386-qemu --- kern/i386/qemu/mmap.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/kern/i386/qemu/mmap.c b/kern/i386/qemu/mmap.c index c7fc4f45e..f2a998e78 100644 --- a/kern/i386/qemu/mmap.c +++ b/kern/i386/qemu/mmap.c @@ -27,21 +27,37 @@ #define QEMU_CMOS_MEMSIZE_HIGH 0x35 #define QEMU_CMOS_MEMSIZE_LOW 0x34 +#define QEMU_CMOS_MEMSIZE2_HIGH 0x31 +#define QEMU_CMOS_MEMSIZE2_LOW 0x30 + #define min(a,b) ((a) > (b) ? (b) : (a)) extern char _start[]; extern char _end[]; -grub_size_t grub_lower_mem, grub_upper_mem; -grub_uint64_t mem_size; +static grub_uint64_t mem_size, above_4g; void grub_machine_mmap_init () { - mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16; + mem_size = ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH)) << 24 + | ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW)) << 16; + if (mem_size > 0) + { + /* Don't ask... */ + mem_size += (16 * 1024 * 1024); + } + else + { + mem_size + = ((((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE2_HIGH)) << 18) + | ((grub_uint64_t) (grub_cmos_read (QEMU_CMOS_MEMSIZE2_LOW)) << 10)) + + 1024 * 1024; + } - /* Don't ask... */ - mem_size += (16 * 1024 * 1024); + above_4g = (((grub_uint64_t) grub_cmos_read (0x5b)) << 16) + | (((grub_uint64_t) grub_cmos_read (0x5c)) << 24) + | (((grub_uint64_t) grub_cmos_read (0x5d)) << 32); } grub_err_t @@ -57,6 +73,12 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin GRUB_MACHINE_MEMORY_RESERVED)) return 1; + /* Everything else is free. */ + if (hook (0x100000, + min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000, + GRUB_MACHINE_MEMORY_AVAILABLE)) + return 1; + /* Protect boot.img, which contains the gdt. It is mapped at the top of memory (it is also mapped below 0x100000, but we already reserved that area). */ if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE, @@ -64,10 +86,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin GRUB_MACHINE_MEMORY_RESERVED)) return 1; - /* Everything else is free. */ - if (hook (0x100000, - min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000, - GRUB_MACHINE_MEMORY_AVAILABLE)) + if (above_4g != 0 && hook (0x100000000ULL, above_4g, + GRUB_MACHINE_MEMORY_AVAILABLE)) return 1; return 0; From d246fc036887fc456b2aa77fa46d45c83e7a7632 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Jun 2010 00:58:43 +0200 Subject: [PATCH 350/503] Improve macroification of VGA registers. --- include/grub/vga.h | 64 +++++++++++++++++++++++++++++++---------- term/i386/pc/vga_text.c | 8 ++++-- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/include/grub/vga.h b/include/grub/vga.h index d05ddd69b..a33cf2b67 100644 --- a/include/grub/vga.h +++ b/include/grub/vga.h @@ -21,6 +21,7 @@ enum { + GRUB_VGA_IO_ARX = 0x3c0, GRUB_VGA_IO_SR_INDEX = 0x3c4, GRUB_VGA_IO_SR_DATA = 0x3c5, GRUB_VGA_IO_PIXEL_MASK = 0x3c6, @@ -41,7 +42,8 @@ enum GRUB_VGA_CR_WIDTH = 0x01, GRUB_VGA_CR_OVERFLOW = 0x07, GRUB_VGA_CR_CELL_HEIGHT = 0x09, - GRUB_VGA_CR_CURSOR = 0x0a, + GRUB_VGA_CR_CURSOR_START = 0x0a, + GRUB_VGA_CR_CURSOR_END = 0x0b, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER = 0x0c, GRUB_VGA_CR_START_ADDR_LOW_REGISTER = 0x0d, GRUB_VGA_CR_CURSOR_ADDR_HIGH = 0x0e, @@ -64,36 +66,68 @@ enum #define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40 #define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3 -#define GRUB_VGA_CR_CURSOR_DISABLE (1 << 5) +enum + { + GRUB_VGA_CR_CURSOR_START_DISABLE = (1 << 5) + }; #define GRUB_VGA_CR_PITCH_DIVISOR 8 -#define GRUB_VGA_CR_MODE_TIMING_ENABLE 0x80 -#define GRUB_VGA_CR_MODE_BYTE_MODE 0x40 -#define GRUB_VGA_CR_MODE_NO_HERCULES 0x02 -#define GRUB_VGA_CR_MODE_NO_CGA 0x01 - enum { - GRUB_VGA_SR_MAP_MASK_REGISTER = 0x02, - GRUB_VGA_SR_MEMORY_MODE = 0x04, + GRUB_VGA_CR_MODE_NO_CGA = 0x01, + GRUB_VGA_CR_MODE_NO_HERCULES = 0x02, + GRUB_VGA_CR_MODE_BYTE_MODE = 0x40, + GRUB_VGA_CR_MODE_TIMING_ENABLE = 0x80 }; -#define GRUB_VGA_SR_MEMORY_MODE_CHAIN4 8 -#define GRUB_VGA_SR_MEMORY_MODE_NORMAL 0 +enum + { + GRUB_VGA_SR_CLOCKING_MODE = 1, + GRUB_VGA_SR_MAP_MASK_REGISTER = 2, + GRUB_VGA_SR_MEMORY_MODE = 4, + }; enum { - GRUB_VGA_GR_READ_MAP_REGISTER = 0x04, + GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK = 1 + }; + +enum + { + GRUB_VGA_SR_MEMORY_MODE_NORMAL = 0, + GRUB_VGA_SR_MEMORY_MODE_CHAIN4 = 8 + }; + +enum + { + GRUB_VGA_GR_DATA_ROTATE = 3, + GRUB_VGA_GR_READ_MAP_REGISTER = 4, GRUB_VGA_GR_MODE = 5, GRUB_VGA_GR_GR6 = 6, + GRUB_VGA_GR_BITMASK = 8, GRUB_VGA_GR_MAX }; -#define GRUB_VGA_GR_GR6_GRAPHICS_MODE 1 +enum + { + GRUB_VGA_TEXT_TEXT_PLANE = 0, + GRUB_VGA_TEXT_ATTR_PLANE = 1, + GRUB_VGA_TEXT_FONT_PLANE = 2 + }; -#define GRUB_VGA_GR_MODE_256_COLOR 0x40 -#define GRUB_VGA_GR_MODE_READ_MODE1 0x08 +enum + { + GRUB_VGA_GR_GR6_GRAPHICS_MODE = 1, + GRUB_VGA_GR_GR6_MMAP_CGA = (3 << 2) + }; + +enum + { + GRUB_VGA_GR_MODE_READ_MODE1 = 0x08, + GRUB_VGA_GR_MODE_ODD_EVEN = 0x10, + GRUB_VGA_GR_MODE_256_COLOR = 0x40 + }; static inline void grub_vga_gr_write (grub_uint8_t val, grub_uint8_t addr) diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index 8bc14cb61..bfa934a40 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -124,11 +124,13 @@ static void grub_vga_text_setcursor (int on) { grub_uint8_t old; - old = grub_vga_cr_read (GRUB_VGA_CR_CURSOR); + old = grub_vga_cr_read (GRUB_VGA_CR_CURSOR_START); if (on) - grub_vga_cr_write (old & ~GRUB_VGA_CR_CURSOR_DISABLE, GRUB_VGA_CR_CURSOR); + grub_vga_cr_write (old & ~GRUB_VGA_CR_CURSOR_START_DISABLE, + GRUB_VGA_CR_CURSOR_START); else - grub_vga_cr_write (old | GRUB_VGA_CR_CURSOR_DISABLE, GRUB_VGA_CR_CURSOR); + grub_vga_cr_write (old | GRUB_VGA_CR_CURSOR_START_DISABLE, + GRUB_VGA_CR_CURSOR_START); } static grub_err_t From 8c0346515d6d9aefaf105c57516bef0c32957cc4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Jun 2010 01:01:26 +0200 Subject: [PATCH 351/503] Add GRUB_PCI_REG_STATUS_*_ENABLE --- include/grub/pci.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/grub/pci.h b/include/grub/pci.h index 89bd1034a..09eebcd6c 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -66,6 +66,9 @@ #define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MAX_LAT 0x3f +#define GRUB_PCI_REG_STATUS_MEMORY_ENABLE 0x02 +#define GRUB_PCI_REG_STATUS_IO_ENABLE 0x01 + typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_MACHINE_EMU From 4d88b9aec7d3fd1786d4e897a8aa7f2cf045365b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Jun 2010 01:02:48 +0200 Subject: [PATCH 352/503] Init cirrus ourselves instead of calling videobios --- boot/i386/qemu/boot.S | 3 - conf/i386-qemu.rmk | 6 +- conf/i386.rmk | 3 + configure.ac | 7 ++ include/grub/i386/qemu/kernel.h | 2 + kern/i386/coreboot/init.c | 3 + kern/i386/qemu/init.c | 152 ++++++++++++++++++++++++++++++++ 7 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 kern/i386/qemu/init.c diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S index 03631a22a..b4d75f776 100644 --- a/boot/i386/qemu/boot.S +++ b/boot/i386/qemu/boot.S @@ -36,9 +36,6 @@ VARIABLE(grub_core_entry_addr) .long 0 1: - /* Process VGA rom. */ - call $0xc000, $0x3 - /* Set up %ds, %ss, and %es. */ xorw %ax, %ax movw %ax, %ds diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 664bef12a..03a18c3a9 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -19,10 +19,13 @@ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile +kern/i386/qemu/init.c_DEPENDENCIES = ascii.h + pkglib_IMAGES += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ + kern/i386/qemu/init.c \ kern/i386/qemu/mmap.c \ kern/i386/halt.c \ kern/main.c kern/device.c \ @@ -35,8 +38,9 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \ 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/vga_text.c term/i386/vga_common.c bus/pci.c \ symlist.c +kernel_img_HEADERS += pci.h kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) diff --git a/conf/i386.rmk b/conf/i386.rmk index 5e1191c1e..28da1be8d 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -60,11 +60,14 @@ serial_mod_SOURCES = term/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) +# On qemu it's compiled in +ifneq ($(platform), qemu) # For pci.mod pkglib_MODULES += pci.mod pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +endif # For lspci.mod pkglib_MODULES += lspci.mod diff --git a/configure.ac b/configure.ac index 4e1dd41d8..085146b68 100644 --- a/configure.ac +++ b/configure.ac @@ -178,13 +178,20 @@ if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) fi +FONT_SOURCE= + for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do if test -e $file ; then + FONT_SOURCE=$file AC_SUBST([FONT_SOURCE], [$file]) break fi done +if test "x$FONT_SOURCE" == x && ( test "x$platform" = xqemu || test "x$platform" = xyeeloong ); then + AC_MSG_ERROR([qemu and yeeloong ports need unifont]) +fi + AC_PROG_INSTALL AC_PROG_AWK AC_PROG_LEX diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index bc0b93d4f..d1599ae3a 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -48,6 +48,8 @@ extern grub_int32_t grub_total_module_size; configuration file are located. */ extern char grub_prefix[]; +void grub_qemu_init_cirrus (void); + #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index f7b837044..84dd30e0b 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -70,6 +70,9 @@ grub_exit (void) void grub_machine_init (void) { +#ifdef GRUB_MACHINE_QEMU + grub_qemu_init_cirrus (); +#endif /* Initialize the console as early as possible. */ grub_vga_text_init (); diff --git a/kern/i386/qemu/init.c b/kern/i386/qemu/init.c new file mode 100644 index 000000000..3bb497e9d --- /dev/null +++ b/kern/i386/qemu/init.c @@ -0,0 +1,152 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 struct {grub_uint8_t r, g, b, a; } colors[] = + { + // {R, G, B, A} + {0x00, 0x00, 0x00, 0xFF}, // 0 = black + {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue + {0x00, 0xA8, 0x00, 0xFF}, // 2 = green + {0x00, 0xA8, 0xA8, 0xFF}, // 3 = cyan + {0xA8, 0x00, 0x00, 0xFF}, // 4 = red + {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta + {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown + {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray + + {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray + {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue + {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green + {0x54, 0xFE, 0xFE, 0xFF}, // 11 = bright cyan + {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red + {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta + {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow + {0xFE, 0xFE, 0xFE, 0xFF} // 15 = white + }; + +#include + +static void +load_font (void) +{ + unsigned i; + + grub_vga_gr_write (0 << 2, GRUB_VGA_GR_GR6); + + grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE); + grub_vga_sr_write (1 << GRUB_VGA_TEXT_FONT_PLANE, + GRUB_VGA_SR_MAP_MASK_REGISTER); + + grub_vga_gr_write (0, GRUB_VGA_GR_DATA_ROTATE); + grub_vga_gr_write (0, GRUB_VGA_GR_MODE); + grub_vga_gr_write (0xff, GRUB_VGA_GR_BITMASK); + + for (i = 0; i < 128; i++) + grub_memcpy ((void *) (0xa0000 + 32 * i), ascii_bitmaps + 16 * (0x7f - i), 16); +} + +static void +load_palette (void) +{ + unsigned i; + for (i = 0; i < 16; i++) + { + grub_outb (i, GRUB_VGA_IO_ARX); + grub_outb (i, GRUB_VGA_IO_ARX); + } + + for (i = 0; i < ARRAY_SIZE (colors); i++) + grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b); +} + +void +grub_qemu_init_cirrus (void) +{ + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) + { + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != 0x0300) + return 0; + + /* FIXME: chooose addresses dynamically. */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH + | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); + grub_pci_write (addr, 0xf2000000 + | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write (addr, GRUB_PCI_REG_STATUS_MEMORY_ENABLE + | GRUB_PCI_REG_STATUS_IO_ENABLE); + + return 1; + } + + grub_pci_iterate (find_card); + + grub_outb (1, 0x3c2); + + load_font (); + + grub_vga_gr_write (GRUB_VGA_GR_GR6_MMAP_CGA, GRUB_VGA_GR_GR6); + grub_vga_gr_write (GRUB_VGA_GR_MODE_ODD_EVEN, GRUB_VGA_GR_MODE); + + grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE); + + grub_vga_sr_write ((1 << GRUB_VGA_TEXT_TEXT_PLANE) + | (1 << GRUB_VGA_TEXT_ATTR_PLANE), + GRUB_VGA_SR_MAP_MASK_REGISTER); + + grub_vga_cr_write (15, GRUB_VGA_CR_CELL_HEIGHT); + grub_vga_cr_write (79, GRUB_VGA_CR_WIDTH); + grub_vga_cr_write (40, GRUB_VGA_CR_PITCH); + + int vert = 25 * 16; + grub_vga_cr_write (vert & 0xff, GRUB_VGA_CR_HEIGHT); + grub_vga_cr_write (((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT) + & GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK) + | ((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT) + & GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK), + GRUB_VGA_CR_OVERFLOW); + + load_palette (); + + grub_outb (0x10, 0x3c0); + grub_outb (0, 0x3c1); + grub_outb (0x14, 0x3c0); + grub_outb (0, 0x3c1); + + grub_vga_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK, + GRUB_VGA_SR_CLOCKING_MODE); + + grub_vga_cr_write (14, GRUB_VGA_CR_CURSOR_START); + grub_vga_cr_write (15, GRUB_VGA_CR_CURSOR_END); + + grub_outb (0x20, 0x3c0); +} From de24ab9b0ded05e34be80dacff3fd706b3b68210 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Jun 2010 02:07:45 +0200 Subject: [PATCH 353/503] Fix grub_vga_palette_write --- include/grub/vga.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grub/vga.h b/include/grub/vga.h index a33cf2b67..d4a1523a7 100644 --- a/include/grub/vga.h +++ b/include/grub/vga.h @@ -185,7 +185,7 @@ static inline void grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, grub_uint8_t b) { - grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX); + grub_outb (addr, GRUB_VGA_IO_PALLETTE_WRITE_INDEX); grub_outb (r, GRUB_VGA_IO_PALLETTE_DATA); grub_outb (g, GRUB_VGA_IO_PALLETTE_DATA); grub_outb (b, GRUB_VGA_IO_PALLETTE_DATA); From a29051ec7fcf61a5b55723ebcbfd5190eb4cd7cf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Jun 2010 02:08:19 +0200 Subject: [PATCH 354/503] Handle double redraw --- commands/videotest.c | 172 ++++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 83 deletions(-) diff --git a/commands/videotest.c b/commands/videotest.c index 390811a71..f6a786e79 100644 --- a/commands/videotest.c +++ b/commands/videotest.c @@ -38,15 +38,8 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), 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; err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); if (err) @@ -54,102 +47,115 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), 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); + { + const char *str; + int texty; + grub_font_t sansbig; + grub_font_t sans; + grub_font_t sanssmall; + grub_font_t fixed; + struct grub_font_glyph *glyph; - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_create_render_target (&text_layer, width, height, + GRUB_VIDEO_MODE_TYPE_RGB + | GRUB_VIDEO_MODE_TYPE_ALPHA); - color = grub_video_map_rgb (0, 0, 0); - grub_video_fill_rect (color, 0, 0, width, height); + grub_video_set_active_render_target (text_layer); - 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); + sansbig = grub_font_get ("Unknown Regular 16"); + sans = grub_font_get ("Unknown Regular 16"); + sanssmall = grub_font_get ("Unknown Regular 16"); + fixed = grub_font_get ("Fixed 20"); + if (! sansbig || ! sans || ! sanssmall || ! fixed) + return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); - color = grub_video_map_rgb (0, 255, 255); - grub_video_fill_rect (color, 100, 100, 100, 100); + glyph = grub_font_get_glyph (fixed, '*'); + grub_font_draw_glyph (glyph, color, 200 ,0); - sansbig = grub_font_get ("Unknown Regular 16"); - sans = grub_font_get ("Unknown Regular 16"); - sanssmall = grub_font_get ("Unknown Regular 16"); - fixed = grub_font_get ("Fixed 20"); - if (! sansbig || ! sans || ! sanssmall || ! fixed) - return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); + color = grub_video_map_rgb (255, 255, 255); - glyph = grub_font_get_glyph (fixed, '*'); - grub_font_draw_glyph (glyph, color, 200 ,0); + 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); - 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); + 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); - 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: + /* 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. */ + 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 */ + /* 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); + 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); + /* 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); - 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(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(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)); + 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, '*'); + 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); - } + 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 < 2; i++) + { + 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); + + 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_swap_buffers (); + } + for (i = 0; i < 5; i++) { color = grub_video_map_rgb (i, 33, 77); From 5410ebd1f6a44c60220ca630ff34520252930f93 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Jun 2010 02:08:48 +0200 Subject: [PATCH 355/503] Don't read outside of VGA screen --- term/i386/pc/vga_text.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c index bfa934a40..717a7576e 100644 --- a/term/i386/pc/vga_text.c +++ b/term/i386/pc/vga_text.c @@ -58,9 +58,11 @@ inc_y (void) else { int x, y; - for (y = 0; y < ROWS; y++) + for (y = 0; y < ROWS - 1; y++) for (x = 0; x < COLS; x++) screen_write_char (x, y, screen_read_char (x, y + 1)); + for (x = 0; x < COLS; x++) + screen_write_char (x, ROWS - 1, ' ' | (grub_console_cur_color << 8)); } } From 994b0c27ea18c86beacb5b025e8491bbac775070 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Jun 2010 02:23:58 +0200 Subject: [PATCH 356/503] Add ChangeLog --- ChangeLog | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9fe3fa8b0..5509a9f05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-06-21 Vladimir Serbinenko + + Initialise VGA video on qemu ourselves. + + * boot/i386/qemu/boot.S: Don't call 0xc000. + * conf/i386-qemu.rmk (kern/i386/qemu/init.c_DEPENDENCIES): New variable. + (kernel_img_SOURCES): Add kern/i386/qemu/init.c and bus/pci.c. + (kernel_img_HEADERS): Add pci.h. + * conf/i386.rmk (pkglib_MODULES) [qemu]: Remove pci.mod. + * configure.ac: Force unifont on qemu and yeeloong. + * include/grub/i386/qemu/kernel.h (grub_qemu_init_cirrus): New proto. + (grub_vga_palette_write): Use correct register. + * kern/i386/coreboot/init.c (grub_machine_init) [GRUB_MACHINE_QEMU]: + Call grub_qemu_init_cirrus. + * kern/i386/qemu/init.c: New file. + * term/i386/pc/vga_text.c (inc_y): Never read outside the screen. + + * commands/videotest.c (grub_cmd_videotest): Handle double buffering. + 2010-06-20 Vladimir Serbinenko Support >3GiB and <16MiB RAM in i386-qemu. From 14d3f08e70aa24328d26f8caea594f2e2fe7536a Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 21 Jun 2010 20:34:30 +0530 Subject: [PATCH 357/503] Fix parallel build. * conf/common.rmk: Add grub_script.tab.h as a grub-script-check dependency. * script/parser.y: #include grub_script.tab.h header. --- ChangeLog | 8 ++++++++ conf/common.rmk | 1 + script/parser.y | 2 ++ 3 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9fe3fa8b0..477ccbbae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-21 BVK Chaitanya + + Fix parallel build. + + * conf/common.rmk: Add grub_script.tab.h as a grub-script-check + dependency. + * script/parser.y: #include grub_script.tab.h header. + 2010-06-20 Vladimir Serbinenko Support >3GiB and <16MiB RAM in i386-qemu. diff --git a/conf/common.rmk b/conf/common.rmk index bf73c2d59..0f67622b5 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -95,6 +95,7 @@ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c kern/misc.c kern/env.c grub_script.tab.c \ grub_script.yy.c grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS) +grub_script_check_DEPENDENCIES = grub_script.tab.h MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst diff --git a/script/parser.y b/script/parser.y index b5815ea8d..e85ba624d 100644 --- a/script/parser.y +++ b/script/parser.y @@ -26,6 +26,7 @@ #define YYLTYPE_IS_TRIVIAL 0 #define YYENABLE_NLS 0 +#include "grub_script.tab.h" %} %union { @@ -126,6 +127,7 @@ word: GRUB_PARSER_TOKEN_NAME { $$ = grub_script_add_arglist (state, 0, $1); } statement: command { $$ = $1; } | function { $$ = 0; } | menuentry { $$ = $1; } +; argument : "case" { $$ = grub_script_add_arglist (state, 0, $1); } | "do" { $$ = grub_script_add_arglist (state, 0, $1); } From d6e98a17d78f44a8cbbb923bd0efe947791059ed Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 21 Jun 2010 17:59:51 +0100 Subject: [PATCH 358/503] * kern/efi/mm.c (grub_efi_mm_init): Handle systems with memory maps larger than MEMORY_MAP_SIZE. --- ChangeLog | 5 +++++ kern/efi/mm.c | 23 ++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 477ccbbae..94fa54713 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-21 Colin Watson + + * kern/efi/mm.c (grub_efi_mm_init): Handle systems with memory maps + larger than MEMORY_MAP_SIZE. + 2010-06-21 BVK Chaitanya Fix parallel build. diff --git a/kern/efi/mm.c b/kern/efi/mm.c index ceb8fc9ba..2abd6325d 100644 --- a/kern/efi/mm.c +++ b/kern/efi/mm.c @@ -346,6 +346,7 @@ grub_efi_mm_init (void) grub_efi_uintn_t desc_size; grub_efi_uint64_t total_pages; grub_efi_uint64_t required_pages; + int mm_status; /* First of all, allocate pages to maintain allocations. */ allocated_pages @@ -361,16 +362,32 @@ grub_efi_mm_init (void) 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) + mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0); + + if (mm_status == 0) + { + grub_efi_free_pages + ((grub_efi_physical_address_t) ((grub_addr_t) memory_map), + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + + memory_map = grub_efi_allocate_pages (0, 2 * BYTES_TO_PAGES (map_size)); + if (! memory_map) + grub_fatal ("cannot allocate memory"); + + mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, + &desc_size, 0); + } + + if (mm_status < 0) grub_fatal ("cannot get memory map"); memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); + filtered_memory_map = memory_map_end; + filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map, desc_size, memory_map_end); From 12cd7239d9bdc39b728bd7865f26b7fc7df5478c Mon Sep 17 00:00:00 2001 From: starous Date: Mon, 21 Jun 2010 21:12:20 +0200 Subject: [PATCH 359/503] Faster OHCI, USB hub support, UHCI portstatus corr. --- bus/usb/ohci.c | 962 +++++++++++++++++++++++++++------------- bus/usb/uhci.c | 19 +- bus/usb/usb.c | 2 +- bus/usb/usbhub.c | 90 +++- bus/usb/usbtrans.c | 7 +- disk/usbms.c | 24 +- include/grub/usbtrans.h | 12 +- 7 files changed, 778 insertions(+), 338 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 47cca7ce4..fed82d129 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -46,6 +46,23 @@ struct grub_ohci_hcca grub_uint8_t reserved[116]; } __attribute__((packed)); +/* OHCI General Transfer Descriptor */ +struct grub_ohci_td +{ + /* Information used to construct the TOKEN packet. */ + grub_uint32_t token; + grub_uint32_t buffer; /* LittleEndian physical address */ + grub_uint32_t next_td; /* LittleEndian physical address */ + grub_uint32_t buffer_end; /* LittleEndian physical address */ + /* next values are not for OHCI HW */ + grub_uint32_t prev_td_phys; /* we need it to find previous TD + * physical address in CPU endian */ + grub_uint32_t link_td; /* pointer to next free/chained TD + * pointer as uint32 */ + grub_uint32_t tr_index; /* index of TD in transfer */ + grub_uint8_t pad[4]; /* padding to 32 bytes */ +} __attribute__((packed)); + /* OHCI Endpoint Descriptor. */ struct grub_ohci_ed { @@ -55,26 +72,33 @@ struct grub_ohci_ed 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 volatile struct grub_ohci_td *grub_ohci_td_t; typedef volatile struct grub_ohci_ed *grub_ohci_ed_t; +/* Experimental change of ED/TD allocation */ +/* Little bit similar as in UHCI */ +/* Implementation assumes: + * 32-bits architecture - XXX: fix for 64-bits + * memory allocated by grub_memalign_dma32 must be continuous + * in virtual and also in physical memory */ struct grub_ohci { volatile grub_uint32_t *iobase; volatile struct grub_ohci_hcca *hcca; grub_uint32_t hcca_addr; struct grub_pci_dma_chunk *hcca_chunk; + grub_ohci_ed_t ed_ctrl; /* EDs for CONTROL */ + grub_uint32_t ed_ctrl_addr; + struct grub_pci_dma_chunk *ed_ctrl_chunk; + grub_ohci_ed_t ed_bulk; /* EDs for BULK */ + grub_uint32_t ed_bulk_addr; + struct grub_pci_dma_chunk *ed_bulk_chunk; + grub_ohci_td_t td; /* TDs */ + grub_uint32_t td_addr; + struct grub_pci_dma_chunk *td_chunk; struct grub_ohci *next; + grub_ohci_td_t td_free; /* Pointer to first free TD */ + int bad_OHCI; }; static struct grub_ohci *ohci; @@ -121,6 +145,34 @@ typedef enum #define GRUB_OHCI_SET_PORT_RESET (1 << 4) #define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) +#define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5) +#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) + +#define GRUB_OHCI_CTRL_EDS 16 +#define GRUB_OHCI_BULK_EDS 16 +#define GRUB_OHCI_TDS 256 + +#define GRUB_OHCI_ED_ADDR_MASK 0x7ff + +#define GRUB_OHCI_ED_PHYS2VIRT(o, bulk, x) ( !(x) ? NULL : ( \ + (bulk) ? \ + (grub_ohci_ed_t)((x) - (o)->ed_bulk_addr + (grub_uint32_t)(o)->ed_bulk) \ + : \ + (grub_ohci_ed_t)((x) - (o)->ed_ctrl_addr + (grub_uint32_t)(o)->ed_ctrl) ) ) + +#define GRUB_OHCI_ED_VIRT2PHYS(o, bulk, x) ( !(x) ? 0 : ( \ + (bulk) ? \ + ((grub_uint32_t)(x) - (grub_uint32_t)(o)->ed_bulk + (o)->ed_bulk_addr) \ + : \ + ((grub_uint32_t)(x) - (grub_uint32_t)(o)->ed_ctrl + (o)->ed_ctrl_addr) ) ) + +#define GRUB_OHCI_TD_PHYS2VIRT(o, x) ( !(x) ? NULL : \ + (grub_ohci_td_t)((x) - (o)->td_addr + (grub_uint32_t)(o)->td) ) + +#define GRUB_OHCI_TD_VIRT2PHYS(o, x) ( !(x) ? 0 : \ + ((grub_uint32_t)(x) - (grub_uint32_t)(o)->td + (o)->td_addr) ) + + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -148,7 +200,8 @@ grub_ohci_pci_iter (grub_pci_device_t dev, struct grub_ohci *o; grub_uint32_t revision; int cs5536; - + int j; + /* Determine IO base address. */ grub_dprintf ("ohci", "pciid = %x\n", pciid); @@ -204,7 +257,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, o = grub_malloc (sizeof (*o)); if (! o) return 1; - + grub_memset ((void*)o, 0, sizeof (*o)); o->iobase = grub_pci_device_map_range (dev, base, 0x800); grub_dprintf ("ohci", "base=%p\n", o->iobase); @@ -212,9 +265,57 @@ grub_ohci_pci_iter (grub_pci_device_t dev, /* Reserve memory for the HCCA. */ o->hcca_chunk = grub_memalign_dma32 (256, 256); if (! o->hcca_chunk) - return 1; + goto fail; o->hcca = grub_dma_get_virt (o->hcca_chunk); o->hcca_addr = grub_dma_get_phys (o->hcca_chunk); + grub_memset ((void*)o->hcca, 0, sizeof(*o->hcca)); + grub_dprintf ("ohci", "hcca: chunk=%p, virt=%p, phys=0x%02x\n", + o->hcca_chunk, o->hcca, o->hcca_addr); + + /* Reserve memory for ctrl EDs. */ + o->ed_ctrl_chunk = grub_memalign_dma32 (16, sizeof(struct grub_ohci_ed)*GRUB_OHCI_CTRL_EDS); + if (! o->ed_ctrl_chunk) + goto fail; + o->ed_ctrl = grub_dma_get_virt (o->ed_ctrl_chunk); + o->ed_ctrl_addr = grub_dma_get_phys (o->ed_ctrl_chunk); + /* Preset EDs */ + grub_memset ((void*)o->ed_ctrl, 0, sizeof(struct grub_ohci_ed) * GRUB_OHCI_CTRL_EDS); + for (j=0; j < GRUB_OHCI_CTRL_EDS; j++) + o->ed_ctrl[j].target = grub_cpu_to_le32 (1 << 14); /* skip */ + + grub_dprintf ("ohci", "EDs-C: chunk=%p, virt=%p, phys=0x%02x\n", + o->ed_ctrl_chunk, o->ed_ctrl, o->ed_ctrl_addr); + + /* Reserve memory for bulk EDs. */ + o->ed_bulk_chunk = grub_memalign_dma32 (16, sizeof(struct grub_ohci_ed)*GRUB_OHCI_BULK_EDS); + if (! o->ed_bulk_chunk) + goto fail; + o->ed_bulk = grub_dma_get_virt (o->ed_bulk_chunk); + o->ed_bulk_addr = grub_dma_get_phys (o->ed_bulk_chunk); + /* Preset EDs */ + grub_memset ((void*)o->ed_bulk, 0, sizeof(struct grub_ohci_ed) * GRUB_OHCI_BULK_EDS); + for (j=0; j < GRUB_OHCI_BULK_EDS; j++) + o->ed_bulk[j].target = grub_cpu_to_le32 (1 << 14); /* skip */ + + grub_dprintf ("ohci", "EDs-B: chunk=%p, virt=%p, phys=0x%02x\n", + o->ed_bulk_chunk, o->ed_bulk, o->ed_bulk_addr); + + /* Reserve memory for TDs. */ + o->td_chunk = grub_memalign_dma32 (32, sizeof(struct grub_ohci_td)*GRUB_OHCI_TDS); + /* Why is it aligned on 32 boundary if spec. says 16 ? + * We have structure 32 bytes long and we don't want cross + * 4K boundary inside structure. */ + if (! o->td_chunk) + goto fail; + o->td_free = o->td = grub_dma_get_virt (o->td_chunk); + o->td_addr = grub_dma_get_phys (o->td_chunk); + /* Preset free TDs chain in TDs */ + grub_memset ((void*)o->td, 0, sizeof(struct grub_ohci_td) * GRUB_OHCI_TDS); + for (j=0; j < (GRUB_OHCI_TDS-1); j++) + o->td[j].link_td = (grub_uint32_t)&o->td[j+1]; + + grub_dprintf ("ohci", "TDs: chunk=%p, virt=%p, phys=0x%02x\n", + o->td_chunk, o->td, o->td_addr); /* Check if the OHCI revision is actually 1.0 as supported. */ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); @@ -286,9 +387,13 @@ grub_ohci_pci_iter (grub_pci_device_t dev, /* Misc. pre-sets. */ o->hcca->donehead = 0; grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + /* We don't want modify CONTROL/BULK HEAD registers. + * So we assign to HEAD registers zero ED from related array + * and we will not use this ED, it will be always skipped. + * It should not produce notable performance penalty (I hope). */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); /* Check OHCI Legacy Support */ @@ -302,9 +407,11 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_dprintf ("ohci", "OHCI Legacy Support disabled.\n"); } - /* Enable the OHCI. */ + /* Enable the OHCI + enable CONTROL and BULK LIST. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, - (2 << 6)); + (2 << 6) + | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE + | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); grub_dprintf ("ohci", "OHCI enable: 0x%02x\n", (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3); @@ -339,10 +446,13 @@ grub_ohci_pci_iter (grub_pci_device_t dev, fail: if (o) + grub_dma_free (o->td_chunk); + grub_dma_free (o->ed_bulk_chunk); + grub_dma_free (o->ed_ctrl_chunk); grub_dma_free (o->hcca_chunk); grub_free (o); - return 0; + return 1; } @@ -370,6 +480,114 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) return 0; } +static grub_ohci_ed_t +grub_ohci_find_ed (struct grub_ohci *o, int bulk, grub_uint32_t target) +{ + grub_ohci_ed_t ed, ed_next; + grub_uint32_t target_addr = target & GRUB_OHCI_ED_ADDR_MASK; + int count; + int i; + + /* Use proper values and structures. */ + if (bulk) + { + count = GRUB_OHCI_BULK_EDS; + ed = o->ed_bulk; + ed_next = GRUB_OHCI_ED_PHYS2VIRT(o, bulk, + grub_le_to_cpu32 (ed->next_ed) ); + } + else + { + count = GRUB_OHCI_CTRL_EDS; + ed = o->ed_ctrl; + ed_next = GRUB_OHCI_ED_PHYS2VIRT(o, bulk, + grub_le_to_cpu32 (ed->next_ed) ); + } + + /* First try to find existing ED with proper target address */ + for (i = 0; ; ) + { + if (i && /* We ignore zero ED */ + ((ed->target & GRUB_OHCI_ED_ADDR_MASK) == target_addr)) + return ed; /* Found proper existing ED */ + i++; + if (ed_next && (i < count)) + { + ed = ed_next; + ed_next = GRUB_OHCI_ED_PHYS2VIRT(o, bulk, + grub_le_to_cpu32 (ed->next_ed) ); + continue; + } + break; + } + /* ED with target_addr does not exist, we have to add it */ + /* Have we any free ED in array ? */ + if (i >= count) /* No. */ + return NULL; + /* Currently we simply take next ED in array, no allocation + * function is used. It should be no problem until hot-plugging + * will be implemented, i.e. until we will need to de-allocate EDs + * of unplugged devices. */ + /* We can link new ED to previous ED safely as the new ED should + * still have set skip bit. */ + ed->next_ed = grub_cpu_to_le32 ( GRUB_OHCI_ED_VIRT2PHYS (o, + bulk, &ed[1])); + return &ed[1]; +} + +static grub_ohci_td_t +grub_ohci_alloc_td (struct grub_ohci *o) +{ + grub_ohci_td_t ret; + + /* Check if there is a Transfer Descriptor available. */ + if (! o->td_free) + return NULL; + + ret = o->td_free; /* Take current free TD */ + o->td_free = (grub_ohci_td_t)ret->link_td; /* Advance to next free TD in chain */ + ret->link_td = 0; /* Reset link_td in allocated TD */ + return ret; +} + +static void +grub_ohci_free_td (struct grub_ohci *o, grub_ohci_td_t td) +{ + grub_memset ( (void*)td, 0, sizeof(struct grub_ohci_td) ); + td->link_td = (grub_uint32_t) o->td_free; /* Cahin new free TD & rest */ + o->td_free = td; /* Change address of first free TD */ +} + +static void +grub_ohci_free_tds (struct grub_ohci *o, grub_ohci_td_t td) +{ + if (!td) + return; + + /* Unchain first TD from previous TD if it is chained */ + if (td->prev_td_phys) + { + grub_ohci_td_t td_prev_virt = GRUB_OHCI_TD_PHYS2VIRT(o, + td->prev_td_phys); + + if (td == (grub_ohci_td_t) td_prev_virt->link_td) + td_prev_virt->link_td = 0; + } + + /* Free all TDs from td (chained by link_td) */ + while (td) + { + grub_ohci_td_t tdprev; + + /* Unlink the queue. */ + tdprev = td; + td = (grub_ohci_td_t) td->link_td; + + /* Free the TD. */ + grub_ohci_free_td (o, tdprev); + } +} + static void grub_ohci_transaction (grub_ohci_td_t td, grub_transfer_type_t type, unsigned int toggle, @@ -398,12 +616,7 @@ grub_ohci_transaction (grub_ohci_td_t td, break; } -#if 0 /* Always generate interrupt */ - /* Generate no interrupts. */ - token |= 7 << 21; -#endif - - /* Set the token. */ + /* Set the token (Always generate interrupt - bits 21-23 = 0). */ token |= toggle << 24; token |= 1 << 25; @@ -437,174 +650,180 @@ 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_uint32_t ed_addr; - struct grub_pci_dma_chunk *ed_chunk, *td_list_chunk; - grub_ohci_td_t td_list; - grub_uint32_t td_list_addr; + grub_ohci_ed_t ed_virt; + int bulk = 0; + grub_ohci_td_t td_head_virt; + grub_ohci_td_t td_current_virt; + grub_ohci_td_t td_next_virt; + grub_ohci_td_t tderr_virt = NULL; grub_uint32_t target; - grub_uint32_t td_tail; - grub_uint32_t td_head; + grub_uint32_t td_head_phys; + grub_uint32_t td_tail_phys; + grub_uint32_t td_last_phys; + grub_uint32_t tderr_phys = 0; grub_uint32_t status; grub_uint32_t control; - grub_usb_err_t err; + grub_uint8_t errcode = 0; + grub_usb_err_t err = GRUB_USB_ERR_NONE; int i; grub_uint64_t maxtime; + grub_uint64_t bad_OHCI_delay = 0; + int err_halt = 0; int err_timeout = 0; int err_unrec = 0; grub_uint32_t intstatus; - grub_uint32_t tderr_addr = 0; - - /* Allocate an Endpoint Descriptor. */ - ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); - if (! ed_chunk) - return GRUB_USB_ERR_INTERNAL; - ed = grub_dma_get_virt (ed_chunk); - ed_addr = grub_dma_get_phys (ed_chunk); - - td_list_chunk = grub_memalign_dma32 (256, sizeof (*td_list) - * (transfer->transcnt + 1)); - if (! td_list_chunk) - { - grub_dma_free (ed_chunk); - return GRUB_USB_ERR_INTERNAL; - } - td_list = grub_dma_get_virt (td_list_chunk); - td_list_addr = grub_dma_get_phys (td_list_chunk); - - grub_dprintf ("ohci", "alloc=%p/0x%x\n", td_list, td_list_addr); - - /* 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_addr - + (i + 1) * sizeof (td_list[0])); - } - -#if 0 /* Better will be enable interrupt on all TDs. */ - /* The last-1 TD token we should change to enable interrupt when TD finishes. - * As OHCI interrupts are disabled, it does only setting of WDH bit in - * HcInterruptStatus register - and that is what we want to safely detect - * normal end of all transactions. */ - td_list[transfer->transcnt - 1].token &= ~(7 << 21); -#endif - - td_list[transfer->transcnt].token = 0; - td_list[transfer->transcnt].buffer = 0; - td_list[transfer->transcnt].buffer_end = 0; - td_list[transfer->transcnt].next_td = - (grub_uint32_t) &td_list[transfer->transcnt]; - - /* Setup the Endpoint Descriptor. */ + /* Pre-set target for ED - we need it to find proper ED */ /* Set the device address. */ target = transfer->devaddr; - /* Set the endpoint. It should be masked, we need 4 bits only. */ target |= (transfer->endpoint & 15) << 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 = td_list_addr; + /* Determine if transfer type is bulk - we need to select proper ED */ + switch (transfer->type) + { + case GRUB_USB_TRANSACTION_TYPE_BULK: + bulk = 1; + break; - td_tail = td_list_addr + transfer->transcnt * sizeof (*td_list); + case GRUB_USB_TRANSACTION_TYPE_CONTROL: + break; - 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); + default : + return GRUB_USB_ERR_INTERNAL; + } + + /* Find proper ED or add new ED */ + ed_virt = grub_ohci_find_ed (o, bulk, target); + if (!ed_virt) + { + grub_dprintf ("ohci","Fatal: No free ED !\n"); + return GRUB_USB_ERR_INTERNAL; + } + + /* Take pointer to first TD from ED */ + td_head_phys = grub_le_to_cpu32 (ed_virt->td_head) & ~0xf; + td_tail_phys = grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf; + + /* Sanity check - td_head should be equal to td_tail */ + if (td_head_phys != td_tail_phys) /* Should never happen ! */ + { + grub_dprintf ("ohci", "Fatal: HEAD is not equal to TAIL !\n"); + grub_dprintf ("ohci", "HEAD = 0x%02x, TAIL = 0x%02x\n", + td_head_phys, td_tail_phys); + /* XXX: Fix: What to do ? */ + return GRUB_USB_ERR_INTERNAL; + } + + /* Now we should handle first TD. If ED is newly allocated, + * we must allocate the first TD. */ + if (!td_head_phys) + { + td_head_virt = grub_ohci_alloc_td (o); + if (!td_head_virt) + return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */ + /* We can set td_head only when ED is not active, i.e. + * when it is newly allocated. */ + ed_virt->td_head = grub_cpu_to_le32 ( GRUB_OHCI_TD_VIRT2PHYS (o, + td_head_virt) ); + ed_virt->td_tail = ed_virt->td_head; + } + else + td_head_virt = GRUB_OHCI_TD_PHYS2VIRT ( o, td_head_phys ); + + /* Set TDs */ + td_last_phys = td_head_phys; /* initial value to make compiler happy... */ + for (i = 0, td_current_virt = td_head_virt; + i < transfer->transcnt; i++) + { + grub_usb_transaction_t tr = &transfer->transactions[i]; + + grub_ohci_transaction (td_current_virt, tr->pid, tr->toggle, + tr->size, tr->data); + + /* Set index of TD in transfer */ + td_current_virt->tr_index = (grub_uint32_t) i; + + /* No IRQ request in TD if bad_OHCI set */ + if (o->bad_OHCI) + td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21); + + /* Remember last used (processed) TD phys. addr. */ + td_last_phys = GRUB_OHCI_TD_VIRT2PHYS (o, td_current_virt); + + /* Allocate next TD */ + td_next_virt = grub_ohci_alloc_td (o); + if (!td_next_virt) /* No free TD, cancel transfer and free TDs except head TD */ + { + if (i) /* if i==0 we have nothing to free... */ + grub_ohci_free_tds (o, + GRUB_OHCI_TD_PHYS2VIRT(o, + grub_le_to_cpu32 (td_head_virt->next_td) ) ); + /* Reset head TD */ + grub_memset ( (void*)td_head_virt, 0, + sizeof(struct grub_ohci_td) ); + grub_dprintf ("ohci", "Fatal: No free TD !"); + return GRUB_USB_ERR_INTERNAL; + } + + /* Chain TDs */ + td_current_virt->link_td = (grub_uint32_t) td_next_virt; + td_current_virt->next_td = grub_cpu_to_le32 ( + GRUB_OHCI_TD_VIRT2PHYS (o, + td_next_virt) ); + td_next_virt->prev_td_phys = GRUB_OHCI_TD_VIRT2PHYS (o, + td_current_virt); + td_current_virt = td_next_virt; + } + + grub_dprintf ("ohci", "Tail TD (not processed) = %p\n", + td_current_virt); + + /* Setup the Endpoint Descriptor for transfer. */ + /* First set necessary fields in TARGET but keep (or set) skip bit */ + /* Note: It could be simpler if speed, format and max. packet + * size never change after first allocation of ED. + * But unfortunately max. packet size may change during initial + * setup sequence and we must handle it. */ + ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); + /* Set td_tail */ + ed_virt->td_tail = grub_cpu_to_le32 ( GRUB_OHCI_TD_VIRT2PHYS (o, + td_current_virt) ); + /* Now reset skip bit */ + ed_virt->target = grub_cpu_to_le32 (target); + /* ed_virt->td_head = grub_cpu_to_le32 (td_head); Must not be changed, it is maintained by OHCI */ + /* ed_virt->next_ed = grub_cpu_to_le32 (0); Handled by grub_ohci_find_ed, do not change ! */ grub_dprintf ("ohci", "program OHCI\n"); - /* 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 &= ~(3 << 1); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - - /* Now we should wait for start of next frame. Because we are not using - * interrupt, we reset SF bit and wait when it goes to 1. */ - /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); - /* Wait for new SOF */ - while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); - /* Now it should be safe to change CONTROL and BULK lists. */ - - /* This we do for safety's sake - it should be done in previous call - * of grub_ohci_transfer and nobody should change it in meantime... - * It should be done before start of control or bulk OHCI list. */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ - /* Program the OHCI to actually transfer. */ switch (transfer->type) { case GRUB_USB_TRANSACTION_TYPE_BULK: { - grub_dprintf ("ohci", "add to bulk list\n"); - - /* Set BulkList Head and Current */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - -#define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5) -#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) - - /* Enable the Bulk list. */ - control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - control |= GRUB_OHCI_REG_CONTROL_BULK_ENABLE; - control &= ~GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; - - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); - + grub_dprintf ("ohci", "BULK list filled\n"); /* Set BulkListFilled. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - status |= 1 << 2; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1 << 2); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); break; } case GRUB_USB_TRANSACTION_TYPE_CONTROL: { - grub_dprintf ("ohci", "add to control list\n"); - - /* Set ControlList Head and Current */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - - /* Enable the Control list. */ - control |= GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; - control &= ~GRUB_OHCI_REG_CONTROL_BULK_ENABLE; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); - + grub_dprintf ("ohci", "CONTROL list filled\n"); /* Set ControlListFilled. */ - status |= 1 << 1; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1 << 1); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); break; } } - grub_dprintf ("ohci", "wait for completion\n"); - grub_dprintf ("ohci", "begin: control=0x%02x status=0x%02x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); - grub_dprintf ("ohci","intstatus=0x%02x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); - /* Safety measure to avoid a hang. */ maxtime = grub_get_time_ms () + 1000; @@ -613,19 +832,22 @@ grub_ohci_transfer (grub_usb_controller_t dev, { /* Check transfer status */ intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - if ((intstatus & 0x2) != 0) + if (!o->bad_OHCI && (intstatus & 0x2) != 0) { - grub_dprintf ("ohci", "Current HccaDoneHead=0x%08x\n", - o->hcca->donehead); /* Remember last successful TD */ - tderr_addr = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; /* Reset DoneHead */ o->hcca->donehead = 0; grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); /* if TD is last, finish */ - if (tderr_addr == td_list_addr - + sizeof (td_list[0]) * (transfer->transcnt - 1)) - break; + if (tderr_phys == td_last_phys) + { + if (grub_le_to_cpu32 (ed_virt->td_head) & 1) + err_halt = 1; + break; + } continue; } @@ -636,102 +858,160 @@ grub_ohci_transfer (grub_usb_controller_t dev, } /* Detected a HALT. */ - if (grub_le_to_cpu32 (ed->td_head) & 1) - break; + if (err_halt || (grub_le_to_cpu32 (ed_virt->td_head) & 1)) + { + err_halt = 1; + /* ED is halted, but donehead event can happened in the meantime */ + intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + if (!o->bad_OHCI && (intstatus & 0x2) != 0) + /* Don't break loop now, first do donehead action(s) */ + continue; + break; + } + /* bad OHCI handling */ + if ( (grub_le_to_cpu32 (ed_virt->td_head) & ~0xf) == + (grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf) ) /* Empty ED */ + { + if (o->bad_OHCI) /* Bad OHCI detected previously */ + { + /* Try get last successful TD. */ + tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + if (tderr_phys)/* Reset DoneHead if we were successful */ + { + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + } + /* Check the HALT bit */ + if (grub_le_to_cpu32 (ed_virt->td_head) & 1) + err_halt = 1; + break; + } + else /* Detection of bad OHCI */ + /* We should wait short time (~2ms) before we say that + * it is bad OHCI to prevent some hazard - + * donehead can react in the meantime. This waiting is done + * only once per OHCI driver "live cycle". */ + if (!bad_OHCI_delay) /* Set delay time */ + bad_OHCI_delay = grub_get_time_ms () + 2; + else if (grub_get_time_ms () >= bad_OHCI_delay) + o->bad_OHCI = 1; + continue; + } + /* Timeout ? */ if (grub_get_time_ms () > maxtime) { - /* Disable the Control and Bulk lists. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~(3 << 4)); err_timeout = 1; break; } - if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) - break; - grub_cpu_idle (); } while (1); - grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); - grub_dprintf ("ohci", "intstatus=0x%02x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); + /* There are many ways how the loop above can finish: + * - normally without any error via INTSTATUS WDH bit + * : tderr_phys == td_last_phys, td_head == td_tail + * - normally with error via HALT bit in ED TD HEAD + * : td_head = next TD after TD with error + * : tderr_phys = last processed and retired TD with error, + * i.e. should be != 0 + * : if bad_OHCI == TRUE, tderr_phys will be probably invalid + * - unrecoverable error - I never seen it but it could be + * : err_unrec == TRUE, other values can contain anything... + * - timeout, it can be caused by: + * -- bad USB device - some devices have some bugs, see Linux source + * and related links + * -- bad OHCI controller - e.g. lost interrupts or does not set + * proper bits in INTSTATUS when real IRQ not enabled etc., + * see Linux source and related links + * One known bug is handled - if transfer finished + * successfully (i.e. HEAD==TAIL, last transfer TD is retired, + * HALT bit is not set) and WDH bit is not set in INTSTATUS - in + * this case we set o->bad_OHCI=TRUE and do alternate loop + * and error handling - but there is problem how to find retired + * TD with error code if HALT occurs and if DONEHEAD is not + * working - we need to find TD previous to current ED HEAD + * -- bad code of this driver or some unknown reasons - :-( + * it can be e.g. bad handling of EDs/TDs/toggle bit... + */ - if (!tderr_addr) + /* Remember target for debug and set skip flag in ED */ + /* It should be normaly not necessary but we need it at least + * in case of timeout */ + target = grub_le_to_cpu32 ( ed_virt->target ); + ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); + /* Read registers for debug - they should be read now because + * debug prints case unwanted delays, so something can happen + * in the meantime... */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + /* Now print debug values - to have full info what happened */ + grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n", + control, status); + grub_dprintf ("ohci", "intstatus=0x%02x \n\t\t tderr_phys=0x%02x, td_last_phys=0x%02x\n", + intstatus, tderr_phys, td_last_phys); + grub_dprintf ("ohci", "err_unrec=%d, err_timeout=%d \n\t\t err_halt=%d, bad_OHCI=%d\n", + err_unrec, err_timeout, err_halt, o->bad_OHCI); + grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n", + target, + grub_le_to_cpu32 (ed_virt->td_head), + grub_le_to_cpu32 (ed_virt->td_tail) ); + + if (!err_halt && !err_unrec && !err_timeout) /* normal finish */ { - /* It means that something wrong happened, - * it could be: - * - timeout and no TD processed - * - some or unrecoverable error and no TD processed - * - something unexpected... :-( */ - /* Try look into DONEHEAD reg., but there should be also zero */ - grub_dprintf("ohci", "HCCA DoneHead is zero, something is bad!\n"); - tderr_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf; + /* Simple workaround if donehead is not working */ + if (o->bad_OHCI && + ( !tderr_phys || (tderr_phys != td_last_phys) ) ) + { + grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n"); + tderr_phys = td_last_phys; + /* I hope we can do it as transfer (most probably) finished OK */ + } + /* Prepare pointer to last processed TD */ + tderr_virt = GRUB_OHCI_TD_PHYS2VIRT (o, tderr_phys); + /* Set index of last processed TD */ + if (tderr_virt) + transfer->last_trans = tderr_virt->tr_index; + else + transfer->last_trans = -1; } - - /* Remember last processed transaction (TD) - it is necessary for - * proper setting of toggle bit in next transaction. */ - transfer->last_trans = ((tderr_addr - td_list_addr) / sizeof (*td_list)); - grub_dprintf("ohci", "tderr_addr=0x%x, td_list_addr=0x%x,\n", - tderr_addr, td_list_addr); - if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) - transfer->last_trans = transfer->transcnt - 1; - - /* Check correct value in last_trans */ - /* It could happen if timeout happens and no TD was retired */ - if (transfer->last_trans >= transfer->transcnt || !tderr_addr) + else if (err_halt) /* error, ED is halted by OHCI, i.e. can be modified */ { - grub_dprintf("ohci", "tderr==0 or out of TDs range!\n"); - grub_dprintf("ohci", "last_trans=%d, transcnt=%d\n", - transfer->last_trans, transfer->transcnt); + /* First we must get proper tderr_phys value */ + if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */ + { + if ( tderr_phys ) /* check if tderr_phys points to TD with error */ + errcode = grub_le_to_cpu32 ( GRUB_OHCI_TD_PHYS2VIRT (o, + tderr_phys)->token ) + >> 28; + if ( !tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */ + { /* Retired TD with error should be previous TD to ED->td_head */ + tderr_phys = GRUB_OHCI_TD_PHYS2VIRT (o, + grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf ) + ->prev_td_phys; + } + } - /* We should set something valid... */ - transfer->last_trans = -1; /* Probably no TD done */ - tderr_addr = td_list_addr; - } - - /* In case of timeout do not detect error from TD */ - if (err_timeout) - { - err = GRUB_ERR_TIMEOUT; - grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n", - grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head)); - grub_dprintf("ohci", "tail=%08x, next=%08x\n", - grub_le_to_cpu32(ed->td_tail), - grub_le_to_cpu32(ed->next_ed)); - } - /* In case of unrecoverable error do not detect error from TD */ - else if (err_unrec) - { - err = GRUB_USB_ERR_UNRECOVERABLE; - grub_dprintf("ohci", - "Unrecoverable error, target=%08x, head=%08x\n", - grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head)); - grub_dprintf("ohci", "tail=%08x, next=%08x\n", - grub_le_to_cpu32(ed->td_tail), - grub_le_to_cpu32(ed->next_ed)); - } - else if (grub_le_to_cpu32 (ed->td_head) & 1) - { - grub_uint8_t errcode; - grub_ohci_td_t tderr = NULL; - - transfer->last_trans--; - - tderr = (grub_ohci_td_t) ((char *) td_list - + (tderr_addr - td_list_addr)); - - errcode = grub_le_to_cpu32 (tderr->token) >> 28; - grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode); + /* Prepare pointer to last processed TD and get error code */ + tderr_virt = GRUB_OHCI_TD_PHYS2VIRT (o, tderr_phys); + /* Set index of last processed TD */ + if (tderr_virt) + { + errcode = grub_le_to_cpu32 ( tderr_virt->token ) >> 28; + transfer->last_trans = tderr_virt->tr_index; + } + else + transfer->last_trans = -1; + /* Evaluation of error code */ + grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n", + tderr_phys, errcode); switch (errcode) { case 0: @@ -777,16 +1057,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* XXX: Data overrun error. */ err = GRUB_USB_ERR_DATA; grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", - tderr, transfer->last_trans); + tderr_virt, tderr_virt->tr_index); break; case 9: /* XXX: Data underrun error. */ err = GRUB_USB_ERR_DATA; grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", - tderr, transfer->last_trans); + tderr_virt, tderr_virt->tr_index); grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n", - 1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer)); + 1 + grub_le_to_cpu32 (tderr_virt->buffer_end) + - grub_le_to_cpu32 (tderr_virt->buffer)); break; case 10: @@ -813,69 +1094,101 @@ grub_ohci_transfer (grub_usb_controller_t dev, err = GRUB_USB_ERR_NAK; break; } + + /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ + ed_virt->td_head = ed_virt->td_tail & ~0xf; } - else - err = GRUB_USB_ERR_NONE; + + else if (err_unrec) + { + /* Don't try to get error code and last processed TD for proper + * toggle bit value - anything can be invalid */ + err = GRUB_USB_ERR_UNRECOVERABLE; + grub_dprintf("ohci", "Unrecoverable error!"); - /* 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); + /* Do OHCI reset in case of unrecoverable error - maybe we will need + * do more - re-enumerate bus etc. (?) */ - /* Clear BulkListFilled and ControlListFilled. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - status &= ~(3 << 1); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - - /* Set ED to be skipped - for safety */ - ed->target |= grub_cpu_to_le32 (1 << 14); - - /* Now we should wait for start of next frame. - * It is necessary because we will invalidate pointer to ED and it - * can be on OHCI active till SOF! - * Because we are not using interrupt, we reset SF bit and wait when - * it goes to 1. */ - /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); - /* Wait for new SOF */ - while (((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0) - && !err_unrec); - /* Now it should be safe to change CONTROL and BULK lists. */ - - /* Important cleaning. */ + /* Suspend the OHCI by issuing a reset. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + grub_millisleep (1); + grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); + + /* Misc. resets. */ + ed_virt->td_head = ed_virt->td_tail & ~0xf; /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + + /* Enable the OHCI. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + (2 << 6) + | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE + | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); + } + + else if (err_timeout) + { + /* In case of timeout do not detect error from TD */ + err = GRUB_ERR_TIMEOUT; + grub_dprintf("ohci", "Timeout !\n"); + + /* We should wait for next SOF to be sure that ED is unaccessed + * by OHCI */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + + /* Now we must find last processed TD if bad_OHCI == TRUE */ + if (o->bad_OHCI) + { /* Retired TD with error should be previous TD to ED->td_head */ + tderr_phys = GRUB_OHCI_TD_PHYS2VIRT (o, + grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf) + ->prev_td_phys; + } + tderr_virt = GRUB_OHCI_TD_PHYS2VIRT (o, tderr_phys); + if (tderr_virt) + transfer->last_trans = tderr_virt->tr_index; + else + transfer->last_trans = -1; + + /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ + ed_virt->td_head = ed_virt->td_tail & ~0xf; + } + + /* At this point always should be: + * ED has skip bit set and halted or empty or after next SOF, + * i.e. it is safe to free all TDs except last not processed + * ED HEAD == TAIL == phys. addr. of td_current_virt */ + + /* Reset DoneHead - sanity cleanup */ o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - if (err_unrec) - { - /* Do OHCI reset in case of unrecoverable error - maybe we will need - * do more - re-enumerate bus etc. (?) */ + /* Un-chainig of last TD */ + if (td_current_virt->prev_td_phys) + { + grub_ohci_td_t td_prev_virt + = GRUB_OHCI_TD_PHYS2VIRT (o, td_current_virt->prev_td_phys); - /* Suspend the OHCI by issuing a reset. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ - grub_millisleep (1); - grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); + td_next_virt = (grub_ohci_td_t) td_prev_virt->link_td; + if (td_current_virt == td_next_virt) + td_prev_virt->link_td = 0; + } - /* Misc. resets. */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - - /* Enable the OHCI. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, (2 << 6)); - } - - grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err); - - grub_dma_free (td_list_chunk); - grub_dma_free (ed_chunk); + grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x, errcode=0x%02x\n", + err, errcode); + grub_ohci_free_tds (o, td_head_virt); return err; } @@ -952,10 +1265,32 @@ grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) for (o = ohci; o; o = o->next) { int i, nports = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & 0xff; + grub_uint64_t maxtime; + + /* Set skip in all EDs */ + if (o->ed_bulk) + for (i=0; i < GRUB_OHCI_BULK_EDS; i++) + o->ed_bulk[i].target |= grub_cpu_to_le32 (1 << 14); /* skip */ + if (o->ed_ctrl) + for (i=0; i < GRUB_OHCI_CTRL_EDS; i++) + o->ed_ctrl[i].target |= grub_cpu_to_le32 (1 << 14); /* skip */ + + /* We should wait for next SOF to be sure that all EDs are + * unaccessed by OHCI. But OHCI can be non-functional, so + * more than 1ms timeout have to be applied. */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + maxtime = grub_get_time_ms () + 2; + /* Wait for new SOF or timeout */ + while ( ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) + == 0) || (grub_get_time_ms () >= maxtime) ); + for (i = 0; i < nports; i++) grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + i, GRUB_OHCI_CLEAR_PORT_ENABLE); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); + grub_millisleep (1); grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); @@ -963,7 +1298,22 @@ grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + +#if 0 /* Is this necessary before booting? Probably not .(?) + * But it must be done if module is removed ! (Or not ?) + * How to do it ? - Probably grub_ohci_restore_hw should be more + * complicated. (?) + * (If we do it, we need to reallocate EDs and TDs in function + * grub_ohci_restore_hw ! */ + + /* Free allocated EDs and TDs */ + grub_dma_free (o->td_chunk); + grub_dma_free (o->ed_bulk_chunk); + grub_dma_free (o->ed_ctrl_chunk); + grub_dma_free (o->hcca_chunk); +#endif } grub_millisleep (10); @@ -976,7 +1326,23 @@ grub_ohci_restore_hw (void) struct grub_ohci *o; for (o = ohci; o; o = o->next) - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); + { + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + + /* Enable the OHCI. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + (2 << 6) + | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE + | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); + } return GRUB_ERR_NONE; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 1510f98e8..e85f07a6f 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -612,8 +612,23 @@ grub_uhci_portstatus (grub_usb_controller_t dev, status = grub_uhci_readreg16 (u, reg); grub_dprintf ("uhci", "detect=0x%02x\n", status); + if (!enable) /* We don't need reset port */ + { + /* Disable the port. */ + grub_uhci_writereg16 (u, reg, 0 << 2); + grub_dprintf ("uhci", "waiting for the port to be disabled\n"); + endtime = grub_get_time_ms () + 1000; + while ((grub_uhci_readreg16 (u, reg) & (1 << 2))) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, "UHCI Timed out"); + + status = grub_uhci_readreg16 (u, reg); + grub_dprintf ("uhci", ">3detect=0x%02x\n", status); + return GRUB_ERR_NONE; + } + /* Reset the port. */ - grub_uhci_writereg16 (u, reg, enable << 9); + grub_uhci_writereg16 (u, reg, 1 << 9); /* Wait for the reset to complete. XXX: How long exactly? */ grub_millisleep (50); /* For root hub should be nominaly 50ms */ @@ -623,7 +638,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_millisleep (10); /* Enable the port. */ - grub_uhci_writereg16 (u, reg, enable << 2); + grub_uhci_writereg16 (u, reg, 1 << 2); grub_millisleep (10); grub_dprintf ("uhci", "waiting for the port to be enabled\n"); diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 9a78f2c4a..4f6f9e54c 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -166,7 +166,7 @@ grub_usb_device_initialize (grub_usb_device_t dev) * max. size of packet */ dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */ err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, - 0, 8, (char *) &dev->descdev); + 0, 8, (char *) &dev->descdev); if (err) return err; diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 48e3ce592..f50418069 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -87,14 +87,47 @@ grub_usb_add_hub (grub_usb_device_t dev) struct grub_usb_usb_hubdesc hubdesc; grub_err_t err; int i; + grub_uint64_t timeout; + grub_usb_device_t next_dev; + + err = 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); + if (err) + return err; + grub_dprintf ("usb", "Hub descriptor:\n\t\t len:%d, typ:0x%02x, cnt:%d, char:0x%02x, pwg:%d, curr:%d\n", + hubdesc.length, hubdesc.type, hubdesc.portcnt, + hubdesc.characteristics, hubdesc.pwdgood, + hubdesc.current); - 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); + /* Activate the first configuration. Hubs should have only one conf. */ + grub_dprintf ("usb", "Hub set configuration\n"); + grub_usb_set_configuration (dev, 1); + /* Power on all Hub ports. */ + for (i = 1; i <= hubdesc.portcnt; i++) + { + grub_dprintf ("usb", "Power on - port %d\n", i); + /* Power on the port and wait for possible device connect */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_POWER, + i, 0, NULL); + /* Just ignore the device if some error happened */ + if (err) + continue; + } + /* Wait for port power-on */ + if (hubdesc.pwdgood >= 50) + grub_millisleep (hubdesc.pwdgood * 2); + else + grub_millisleep (100); + /* Iterate over the Hub ports. */ for (i = 1; i <= hubdesc.portcnt; i++) { @@ -104,14 +137,14 @@ grub_usb_add_hub (grub_usb_device_t dev) 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, + GRUB_USB_REQ_GET_STATUS, 0, i, sizeof (status), (char *) &status); - /* Just ignore the device if the Hub does not report the status. */ if (err) continue; - + grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status); + /* If connected, reset and enable the port. */ if (status & GRUB_USB_HUB_STATUS_CONNECTED) { @@ -128,21 +161,46 @@ grub_usb_add_hub (grub_usb_device_t dev) 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! */ + /* A device is actually connected to this port. + * Now do reset of port. */ + grub_dprintf ("usb", "Reset hub port - port %d\n", i); err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_TARGET_OTHER), - 0x3, 0x4, i, 0, 0); - + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_RESET, + i, 0, 0); /* If the Hub does not cooperate for this port, just skip the port. */ if (err) continue; + /* Wait for reset procedure done */ + timeout = grub_get_time_ms () + 1000; + do + { + /* 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_GET_STATUS, + 0, i, sizeof (status), (char *) &status); + } + while (!err && + !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) && + (grub_get_time_ms() < timeout) ); + if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) ) + continue; + /* Add the device and assign a device address to it. */ - grub_usb_hub_add_dev (&dev->controller, speed); + grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i); + next_dev = grub_usb_hub_add_dev (&dev->controller, speed); + if (! next_dev) + continue; + + /* If the device is a Hub, scan it for more devices. */ + if (next_dev->descdev.class == 0x09) + grub_usb_add_hub (next_dev); } } @@ -156,7 +214,7 @@ attach_root_port (grub_usb_controller_t controller, int portno, grub_usb_device_t dev; grub_err_t err; - /* Enable the port. */ + /* Disable the port. XXX: Why? */ err = controller->dev->portstatus (controller, portno, 0); if (err) return; diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index e1b9097e6..4a55cab11 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -81,7 +81,7 @@ grub_usb_control_msg (grub_usb_device_t dev, else max = 64; - grub_dprintf ("usb", "transfer = %p, dev = %p\n", transfer, dev); + grub_dprintf ("usb", "control: transfer = %p, dev = %p\n", transfer, dev); datablocks = (size + max - 1) / max; @@ -146,6 +146,7 @@ grub_usb_control_msg (grub_usb_device_t dev, transfer->transactions[datablocks + 1].toggle = 1; err = dev->controller.dev->transfer (&dev->controller, transfer); + grub_dprintf ("usb", "control: err=%d\n", err); grub_free (transfer->transactions); @@ -174,6 +175,8 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, struct grub_pci_dma_chunk *data_chunk; grub_size_t size = size0; + grub_dprintf ("usb", "bulk: size=0x%02x type=%d\n", size, type); + /* FIXME: avoid allocation any kind of buffer in a first place. */ data_chunk = grub_memalign_dma32 (128, size); if (!data_chunk) @@ -248,7 +251,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1; else toggle = dev->toggle[endpoint]; /* Nothing done, take original */ - grub_dprintf ("usb", "toggle=%d\n", toggle); + grub_dprintf ("usb", "bulk: err=%d, toggle=%d\n", err, toggle); dev->toggle[endpoint] = toggle; grub_free (transfer->transactions); diff --git a/disk/usbms.c b/disk/usbms.c index 5550ff770..654e40c36 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -239,7 +239,6 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, grub_usb_err_t err = GRUB_USB_ERR_NONE; grub_usb_err_t errCSW = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; - grub_size_t i; retry: retrycnt--; @@ -293,30 +292,27 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, goto CheckCSW; } /* Debug print of received data. */ - grub_dprintf ("usb", "buf:\n"); - if (size <= 64) - for (i=0; idev, dev->out->endp_addr, size, buf); grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); - grub_dprintf ("usb", "buf:\n"); + grub_dprintf ("usb", "First 16 bytes of sent data:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + buf[ 0], buf[ 1], buf[ 2], buf[ 3], + buf[ 4], buf[ 5], buf[ 6], buf[ 7], + buf[ 8], buf[ 9], buf[10], buf[11], + buf[12], buf[13], buf[14], buf[15]); if (err) { if (err == GRUB_USB_ERR_STALL) grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto CheckCSW; } - /* Debug print of sent data. */ - if (size <= 256) - for (i=0; i Date: Wed, 23 Jun 2010 09:16:39 +0100 Subject: [PATCH 360/503] Sync up other versions of the Linux loader with Robert Millan's change of 2010-01-09, "Make loader output a bit more user-friendly". * loader/i386/efi/linux.c (grub_linux_boot): Move debug info to grub_dprintf(). (grub_cmd_linux): Likewise. (grub_cmd_initrd): Likewise. * loader/i386/ieee1275/linux.c (grub_cmd_linux): Likewise. * loader/i386/pc/linux.c (grub_cmd_linux): Likewise. --- ChangeLog | 12 ++++++++++++ loader/i386/efi/linux.c | 14 +++++++------- loader/i386/ieee1275/linux.c | 4 ++-- loader/i386/pc/linux.c | 5 +++-- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 94fa54713..b97f05d19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-06-23 Colin Watson + + Sync up other versions of the Linux loader with Robert Millan's + change of 2010-01-09, "Make loader output a bit more user-friendly". + + * loader/i386/efi/linux.c (grub_linux_boot): Move debug info to + grub_dprintf(). + (grub_cmd_linux): Likewise. + (grub_cmd_initrd): Likewise. + * loader/i386/ieee1275/linux.c (grub_cmd_linux): Likewise. + * loader/i386/pc/linux.c (grub_cmd_linux): Likewise. + 2010-06-21 Colin Watson * kern/efi/mm.c (grub_efi_mm_init): Handle systems with memory maps diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 4a0eae58b..d37feb983 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -418,9 +418,9 @@ grub_linux_boot (void) grub_mmap_iterate (hook); params->mmap_size = e820_num; - grub_printf ("Trampoline at %p. code32=%x, real_mode_mem=%p\n", - ((char *) prot_mode_mem + (prot_mode_pages << 12)), - (unsigned) params->code32_start, real_mode_mem); + grub_dprintf ("linux", "Trampoline at %p. code32=%x, real_mode_mem=%p\n", + ((char *) prot_mode_mem + (prot_mode_pages << 12)), + (unsigned) params->code32_start, real_mode_mem); modevar = grub_env_get ("gfxpayload"); @@ -732,8 +732,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 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); + grub_dprintf ("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; @@ -913,8 +913,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), goto fail; } - grub_printf (" [Initrd, addr=0x%x, size=0x%x]\n", - (unsigned) addr, (unsigned) size); + grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n", + (unsigned) addr, (unsigned) size); lh->ramdisk_image = addr; lh->ramdisk_size = size; diff --git a/loader/i386/ieee1275/linux.c b/loader/i386/ieee1275/linux.c index 8780804fd..9f7556ffa 100644 --- a/loader/i386/ieee1275/linux.c +++ b/loader/i386/ieee1275/linux.c @@ -205,8 +205,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 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_dprintf ("linux", "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) diff --git a/loader/i386/pc/linux.c b/loader/i386/pc/linux.c index 0fa9abc12..04bc66661 100644 --- a/loader/i386/pc/linux.c +++ b/loader/i386/pc/linux.c @@ -182,8 +182,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", - grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, prot_size); + grub_dprintf ("linux", "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) From e9b29642bd671973c5747a58124b135a29de66ad Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 23 Jun 2010 09:22:03 +0100 Subject: [PATCH 361/503] * loader/i386/multiboot_mbi.c (retrieve_video_parameters): Set red field position and mask size to red fields from mode_info, not green. * loader/multiboot_mbi2.c (retrieve_video_parameters): Likewise. Remove redundant tag->common.framebuffer_type assignment. Reported by: Seth Goldberg. --- ChangeLog | 9 +++++++++ loader/i386/multiboot_mbi.c | 4 ++-- loader/multiboot_mbi2.c | 5 ++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b97f05d19..b37f0eff7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-06-23 Colin Watson + + * loader/i386/multiboot_mbi.c (retrieve_video_parameters): Set red + field position and mask size to red fields from mode_info, not + green. + * loader/multiboot_mbi2.c (retrieve_video_parameters): Likewise. + Remove redundant tag->common.framebuffer_type assignment. + Reported by: Seth Goldberg. + 2010-06-23 Colin Watson Sync up other versions of the Linux loader with Robert Millan's diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 3d974f04e..d984e4e4e 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -295,8 +295,8 @@ retrieve_video_parameters (struct multiboot_info *mbi, else { mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; - mbi->framebuffer_red_field_position = mode_info.green_field_pos; - mbi->framebuffer_red_mask_size = mode_info.green_mask_size; + mbi->framebuffer_red_field_position = mode_info.red_field_pos; + mbi->framebuffer_red_mask_size = mode_info.red_mask_size; mbi->framebuffer_green_field_position = mode_info.green_field_pos; mbi->framebuffer_green_mask_size = mode_info.green_mask_size; mbi->framebuffer_blue_field_position = mode_info.blue_field_pos; diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c index c9e52e51f..3ad6a6c4a 100644 --- a/loader/multiboot_mbi2.c +++ b/loader/multiboot_mbi2.c @@ -441,9 +441,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) else { tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; - tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; - tag->framebuffer_red_field_position = mode_info.green_field_pos; - tag->framebuffer_red_mask_size = mode_info.green_mask_size; + tag->framebuffer_red_field_position = mode_info.red_field_pos; + tag->framebuffer_red_mask_size = mode_info.red_mask_size; tag->framebuffer_green_field_position = mode_info.green_field_pos; tag->framebuffer_green_mask_size = mode_info.green_mask_size; tag->framebuffer_blue_field_position = mode_info.blue_field_pos; From 3fa06487244de28f6d219be3bd8e040747aaa759 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 26 Jun 2010 10:46:54 +0100 Subject: [PATCH 362/503] Make the `source' command slightly faster. * normal/main.c (grub_normal_execute): Don't re-read list files when nested. --- ChangeLog | 7 +++++++ normal/main.c | 12 ++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b37f0eff7..52b37640f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-26 Colin Watson + + Make the `source' command slightly faster. + + * normal/main.c (grub_normal_execute): Don't re-read list files when + nested. + 2010-06-23 Colin Watson * loader/i386/multiboot_mbi.c (retrieve_video_parameters): Set red diff --git a/normal/main.c b/normal/main.c index fdd3c558c..7275b6367 100644 --- a/normal/main.c +++ b/normal/main.c @@ -464,11 +464,15 @@ void grub_normal_execute (const char *config, int nested, int batch) { grub_menu_t menu = 0; - const char *prefix = grub_env_get ("prefix"); + const char *prefix; - read_lists (prefix); - grub_register_variable_hook ("prefix", NULL, read_lists_hook); - grub_command_execute ("parser.grub", 0, 0); + if (! nested) + { + prefix = grub_env_get ("prefix"); + read_lists (prefix); + grub_register_variable_hook ("prefix", NULL, read_lists_hook); + grub_command_execute ("parser.grub", 0, 0); + } if (config) { From d8034603577f4712649abb260d2c5f1032e37b89 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 26 Jun 2010 10:50:39 +0100 Subject: [PATCH 363/503] * docs/grub.texi (Simple configuration): Explain that GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY must be set to `true' to disable their respective recovery entries, not merely set. --- ChangeLog | 7 +++++++ docs/grub.texi | 15 +++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52b37640f..d76683823 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-26 Colin Watson + + * docs/grub.texi (Simple configuration): Explain that + GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY must be + set to `true' to disable their respective recovery entries, not + merely set. + 2010-06-26 Colin Watson Make the `source' command slightly faster. diff --git a/docs/grub.texi b/docs/grub.texi index 822849777..98d3c5f00 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -911,10 +911,11 @@ A command to configure the serial port when using the serial console. Command-line arguments to add to menu entries for the Linux kernel. @item GRUB_CMDLINE_LINUX_DEFAULT -Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set, two menu entries will be -generated for each Linux kernel: one default entry and one entry for -recovery mode. This option lists command-line arguments to add only to the -default menu entry, after those listed in @samp{GRUB_CMDLINE_LINUX}. +Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set to @samp{true}, two menu +entries will be generated for each Linux kernel: one default entry and one +entry for recovery mode. This option lists command-line arguments to add +only to the default menu entry, after those listed in +@samp{GRUB_CMDLINE_LINUX}. @item GRUB_CMDLINE_NETBSD @itemx GRUB_CMDLINE_NETBSD_DEFAULT @@ -929,10 +930,12 @@ usually more reliable, but in some cases it may not be appropriate. To disable the use of UUIDs, set this option to @samp{true}. @item GRUB_DISABLE_LINUX_RECOVERY -Disable the generation of recovery mode menu entries for Linux. +If this option is set to @samp{true}, disable the generation of recovery +mode menu entries for Linux. @item GRUB_DISABLE_NETBSD_RECOVERY -Disable the generation of recovery mode menu entries for NetBSD. +If this option is set to @samp{true}, disable the generation of recovery +mode menu entries for NetBSD. @item GRUB_VIDEO_BACKEND If graphical video support is required, either because the @samp{gfxterm} From c75be4fb0c28a3124aaabf8e064d07b057205ef0 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sat, 26 Jun 2010 20:31:40 +0100 Subject: [PATCH 364/503] * util/grub.d/10_linux.in: Add support for initrd images on Fedora 13. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d76683823..a002be299 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-26 Pavel Roskin + + * util/grub.d/10_linux.in: Add support for initrd images on Fedora + 13. + 2010-06-26 Colin Watson * docs/grub.texi (Simple configuration): Explain that diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 4b5ddb9d8..9e1450f51 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -117,8 +117,9 @@ while [ "x$list" != "x" ] ; do initrd= for i in "initrd.img-${version}" "initrd-${version}.img" \ - "initrd-${version}" "initrd.img-${alt_version}" \ - "initrd-${alt_version}.img" "initrd-${alt_version}"; do + "initrd-${version}" "initramfs-${version}.img" \ + "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ + "initrd-${alt_version}" "initramfs-${alt_version}.img"; do if test -e "${dirname}/${i}" ; then initrd="$i" break From d86e186ff12d6c09ea184a8791ede5c806c674ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Jun 2010 02:24:08 +0200 Subject: [PATCH 365/503] Fix detection of dom0 kernels --- util/grub.d/20_linux_xen.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 862f43888..9a0136a76 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -85,8 +85,10 @@ EOF EOF } -linux_list=`for i in /boot/vmlinu[xz]-*jeremy* /vmlinu[xz]-*jeremy* ; do - if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi +linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do + basename=$(basename $i) + version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") + if grub_file_is_not_garbage "$i" && grep -qx "CONFIG_XEN_DOM0=y" /boot/config-${version} 2> /dev/null ; then echo -n "$i " ; fi done` xen_list=`for i in /boot/xen*; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi From bbe346529e999e09dc1aed179c50eed090d28bd3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Jun 2010 08:51:46 +0100 Subject: [PATCH 366/503] * commands/cat.c (options): New variable. (grub_cmd_cat): Parse options. If the --dos option is given, print DOS-style "\r\n" line endings as simple newlines (Debian bug #586358). (GRUB_MOD_INIT): Use extcmd. (GRUB_MOD_FINI): Likewise. * docs/grub.texi (cat): Document --dos. --- ChangeLog | 10 ++++++++++ commands/cat.c | 31 +++++++++++++++++++++++-------- docs/grub.texi | 8 +++++++- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index e14460b2f..7f0cc8ba5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-06-28 Colin Watson + + * commands/cat.c (options): New variable. + (grub_cmd_cat): Parse options. If the --dos option is given, print + DOS-style "\r\n" line endings as simple newlines (Debian bug + #586358). + (GRUB_MOD_INIT): Use extcmd. + (GRUB_MOD_FINI): Likewise. + * docs/grub.texi (cat): Document --dos. + 2010-06-28 Vladimir Serbinenko XEN with Linux grub-mkconfig support. diff --git a/commands/cat.c b/commands/cat.c index 3bdafc4c6..4c0e19bc2 100644 --- a/commands/cat.c +++ b/commands/cat.c @@ -23,19 +23,28 @@ #include #include #include -#include +#include #include -static grub_err_t -grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) +static const struct grub_arg_option options[] = + { + {"dos", -1, 0, N_("Accept DOS-style CR/NL line endings."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; +static grub_err_t +grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args) { + struct grub_arg_list *state = cmd->state; + int dos = 0; grub_file_t file; char buf[GRUB_DISK_SECTOR_SIZE]; grub_ssize_t size; int key = 0; + if (state[0].set) + dos = 1; + if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); @@ -54,6 +63,11 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') grub_putchar (c); + else if (dos && c == '\r' && buf[i + 1] == '\n') + { + grub_putchar ('\n'); + i++; + } else { grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); @@ -74,15 +88,16 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), return 0; } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(cat) { - cmd = grub_register_command_p1 ("cat", grub_cmd_cat, - N_("FILE"), N_("Show the contents of a file.")); + cmd = grub_register_extcmd ("cat", grub_cmd_cat, GRUB_COMMAND_FLAG_BOTH, + N_("FILE"), N_("Show the contents of a file."), + options); } GRUB_MOD_FINI(cat) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } diff --git a/docs/grub.texi b/docs/grub.texi index 98d3c5f00..c1981633f 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1624,13 +1624,19 @@ a menu entry). @node cat @subsection cat -@deffn Command cat file +@deffn Command cat [@option{--dos}] 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 + +If the @option{--dos} option is used, then carriage return / new line pairs +will be displayed as a simple new line. Otherwise, the carriage return will +be displayed as a control character (@samp{}) to make it easier to see +when boot problems are caused by a file formatted using DOS-style line +endings. @end deffn From cb88052ba36b1deb8ed91b703b258645b0876457 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Jun 2010 08:55:05 +0100 Subject: [PATCH 367/503] Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible on Linux. * util/deviceiter.c (check_device): Rename to ... (check_device_readable_unique): ... this. Update all callers. Maintain and check a list of which devices (by canonicalized name) have already been seen. (clear_seen_devices): New function. (compare_file_names) [__linux__]: New function. (grub_util_iterate_devices): Clear the list of seen devices on exit and (just in case) on entry. (grub_util_iterate_devices) [__linux__]: Iterate over non-partition devices in /dev/disk/by-id/, in sorted order. Remove DM-RAID seen-devices list, superseded by general code in check_device. --- ChangeLog | 17 ++++ util/deviceiter.c | 214 ++++++++++++++++++++++++++++++---------------- 2 files changed, 159 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f0cc8ba5..fe6461760 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2010-06-28 Colin Watson + + Change grub-mkdevicemap to emit /dev/disk/by-id/ names where + possible on Linux. + + * util/deviceiter.c (check_device): Rename to ... + (check_device_readable_unique): ... this. Update all callers. + Maintain and check a list of which devices (by canonicalized name) + have already been seen. + (clear_seen_devices): New function. + (compare_file_names) [__linux__]: New function. + (grub_util_iterate_devices): Clear the list of seen devices on exit + and (just in case) on entry. + (grub_util_iterate_devices) [__linux__]: Iterate over non-partition + devices in /dev/disk/by-id/, in sorted order. Remove DM-RAID + seen-devices list, superseded by general code in check_device. + 2010-06-28 Colin Watson * commands/cat.c (options): New variable. diff --git a/util/deviceiter.c b/util/deviceiter.c index c3bc508dd..e3a0ab76d 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -345,18 +346,37 @@ get_xvd_disk_name (char *name, int unit) } #endif -/* Check if DEVICE can be read. If an error occurs, return zero, - otherwise return non-zero. */ -static int -check_device (const char *device) +static struct seen_device { + struct seen_device *next; + const char *name; +} *seen; + +/* Check if DEVICE can be read. Skip any DEVICE that we have already seen. + If an error occurs, return zero, otherwise return non-zero. */ +static int +check_device_readable_unique (const char *device) +{ + char *real_device; char buf[512]; FILE *fp; + struct seen_device *seen_elt; /* If DEVICE is empty, just return error. */ if (*device == 0) return 0; + /* Have we seen this device already? */ + real_device = canonicalize_file_name (device); + if (! real_device) + return 0; + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), real_device)) + { + grub_dprintf ("deviceiter", "Already seen %s (%s)\n", + device, real_device); + goto fail; + } + fp = fopen (device, "r"); if (! fp) { @@ -379,7 +399,7 @@ check_device (const char *device) break; } /* Error opening the device. */ - return 0; + goto fail; } /* Make sure CD-ROMs don't get assigned a BIOS disk number @@ -387,7 +407,7 @@ check_device (const char *device) #ifdef __linux__ # ifdef CDROM_GET_CAPABILITY if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0) - return 0; + goto fail; # else /* ! CDROM_GET_CAPABILITY */ /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */ { @@ -395,14 +415,14 @@ check_device (const char *device) struct stat st; if (fstat (fileno (fp), &st)) - return 0; + goto fail; /* 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; + goto fail; } # endif /* ! CDROM_GET_CAPABILITY */ #endif /* __linux__ */ @@ -410,7 +430,7 @@ check_device (const char *device) #if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) # ifdef CDIOCCLRDEBUG if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0) - return 0; + goto fail; # endif /* CDIOCCLRDEBUG */ #endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ @@ -418,21 +438,43 @@ check_device (const char *device) if (fread (buf, 1, 512, fp) != 512) { fclose (fp); - return 0; + goto fail; } + /* Remember that we've seen this device. */ + seen_elt = xmalloc (sizeof (*seen_elt)); + seen_elt->name = real_device; /* steal memory */ + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + fclose (fp); return 1; + +fail: + free (real_device); + return 0; +} + +static void +clear_seen_devices (void) +{ + while (seen) + { + struct seen_device *seen_elt = seen; + seen = seen->next; + free (seen_elt); + } + seen = NULL; } #ifdef __linux__ -# ifdef HAVE_DEVICE_MAPPER -struct dmraid_seen +/* Like strcmp, but doesn't require a cast for use as a qsort comparator. */ +static int +compare_file_names (const void *a, const void *b) { - struct dmraid_seen *next; - const char *name; -}; -# endif /* HAVE_DEVICE_MAPPER */ + const char *left = *(const char **) a; + const char *right = *(const char **) b; + return strcmp (left, right); +} #endif /* __linux__ */ void @@ -441,6 +483,8 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), { int i; + clear_seen_devices (); + /* Floppies. */ for (i = 0; i < floppy_disks; i++) { @@ -450,13 +494,63 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), 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. */ + /* In floppies, write the map, whether check_device_readable_unique + succeeds or not, because the user just may not insert floppies. */ if (hook (name, 1)) - return; + goto out; } #ifdef __linux__ + { + DIR *dir = opendir ("/dev/disk/by-id"); + + if (dir) + { + struct dirent *entry; + char **names; + size_t names_len = 0, names_max = 1024, i; + + names = xmalloc (names_max * sizeof (*names)); + + /* Dump all the directory entries into names, resizing if + necessary. */ + for (entry = readdir (dir); entry; entry = readdir (dir)) + { + /* Skip partition entries. */ + if (strstr (entry->d_name, "-part")) + continue; + if (names_len >= names_max) + { + names_max *= 2; + names = xrealloc (names, names_max * sizeof (*names)); + } + names[names_len++] = xasprintf (entry->d_name); + } + + /* /dev/disk/by-id/ usually has a few alternative identifications of + devices (e.g. ATA vs. SATA). check_device_readable_unique will + ensure that we only get one for any given disk, but sort the list + so that the choice of which one we get is stable. */ + qsort (names, names_len, sizeof (*names), &compare_file_names); + + closedir (dir); + + /* Now add all the devices in sorted order. */ + for (i = 0; i < names_len; ++i) + { + char *path = xasprintf ("/dev/disk/by-id/%s", names[i]); + if (check_device_readable_unique (path)) + { + if (hook (path, 0)) + goto out; + } + free (path); + free (names[i]); + } + free (names); + } + } + if (have_devfs ()) { i = 0; @@ -476,10 +570,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), { strcat (name, "/disc"); if (hook (name, 0)) - return; + goto out; } } - return; + goto out; } #endif /* __linux__ */ @@ -489,10 +583,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[16]; get_ide_disk_name (name, i); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } @@ -503,10 +597,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[16]; get_virtio_disk_name (name, i); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } @@ -516,10 +610,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[20]; get_ataraid_disk_name (name, i); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } @@ -529,10 +623,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[16]; get_xvd_disk_name (name, i); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } #endif /* __linux__ */ @@ -543,10 +637,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[16]; get_scsi_disk_name (name, i); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } @@ -566,10 +660,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[24]; get_dac960_disk_name (name, controller, drive); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } } @@ -587,10 +681,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[24]; get_acceleraid_disk_name (name, controller, drive); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } } @@ -608,10 +702,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[24]; get_cciss_disk_name (name, controller, drive); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } } @@ -629,10 +723,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[24]; get_ida_disk_name (name, controller, drive); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } } @@ -647,10 +741,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[24]; get_i2o_disk_name (name, unit); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } } @@ -661,10 +755,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), char name[16]; get_mmc_disk_name (name, i); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) - return; + goto out; } } @@ -685,7 +779,6 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), unsigned int next = 0; void *top_handle, *second_handle; struct dm_tree_node *root, *top, *second; - struct dmraid_seen *seen = NULL; /* Build DM tree for all devices. */ tree = dm_tree_create (); @@ -721,7 +814,6 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), { const char *node_name, *node_uuid; char *name; - struct dmraid_seen *seen_elt; node_name = dm_tree_node_get_name (second); dmraid_check (node_name, "dm_tree_node_get_name failed\n"); @@ -733,40 +825,21 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), goto dmraid_next_child; } - /* Have we already seen this node? There are typically very few - DM-RAID disks, so a list should be fast enough. */ - if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) - { - grub_dprintf ("deviceiter", "Already seen DM device %s\n", - node_name); - goto dmraid_next_child; - } - name = xasprintf ("/dev/mapper/%s", node_name); - if (check_device (name)) + if (check_device_readable_unique (name)) { if (hook (name, 0)) { free (name); - while (seen) - { - struct dmraid_seen *seen_elt = seen; - seen = seen->next; - free (seen_elt); - } if (task) dm_task_destroy (task); if (tree) dm_tree_free (tree); - return; + goto out; } } free (name); - seen_elt = xmalloc (sizeof *seen_elt); - seen_elt->name = node_name; - grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); - dmraid_next_child: second = dm_tree_next_child (&second_handle, top, 1); } @@ -774,12 +847,6 @@ dmraid_next_child: } dmraid_end: - while (seen) - { - struct dmraid_seen *seen_elt = seen; - seen = seen->next; - free (seen_elt); - } if (task) dm_task_destroy (task); if (tree) @@ -787,5 +854,8 @@ dmraid_end: } # endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ + +out: + clear_seen_devices (); } From c06e40f7286a568b1237b968fdb3824b158d590a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Jun 2010 09:06:41 +0100 Subject: [PATCH 368/503] * util/grub-install.in: Add --debug-image= option. --- ChangeLog | 4 ++++ util/grub-install.in | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe6461760..1d89f5cbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-28 Colin Watson + + * util/grub-install.in: Add --debug-image= option. + 2010-06-28 Colin Watson Change grub-mkdevicemap to emit /dev/disk/by-id/ names where diff --git a/util/grub-install.in b/util/grub-install.in index c7e087dd0..4a5b5a1c3 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -50,6 +50,7 @@ no_floppy= force_lba= recheck=no debug=no +debug_image= if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then disk_module=biosdisk @@ -180,6 +181,11 @@ do # This is an undocumented feature... --debug) debug=yes ;; + --debug-image) + debug_image=`argument $option "$@"`; shift;; + --debug-image=*) + debug_image=`echo "$option" | sed 's/--debug-image=//'` ;; + -f | --force) setup_force="--force" ;; @@ -349,6 +355,13 @@ fi prefix_drive= config_opt= +rm -f ${grubdir}/load.cfg + +if [ "x${debug_image}" != x ]; then + echo "set debug='${debug_image}'" >> ${grubdir}/load.cfg + config_opt="-c ${grubdir}/load.cfg " +fi + if [ "x${devabstraction_module}" = "x" ] ; then if [ x"${install_device}" != x ]; then if echo "${install_device}" | grep -qx "(.*)" ; then @@ -369,7 +382,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 exit 1 fi - echo "search.fs_uuid ${uuid} root " > ${grubdir}/load.cfg + echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" @@ -379,7 +392,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 exit 1 fi - echo "search.fs_uuid ${uuid} root " > ${grubdir}/load.cfg + echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" From dec53e635c422f68b2e6b0d532b64f4317f211f9 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 28 Jun 2010 10:17:57 +0200 Subject: [PATCH 369/503] * mmap/i386/pc/mmap_helper.S: Set CF on return. --- ChangeLog | 4 ++++ mmap/i386/pc/mmap_helper.S | 14 ++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d89f5cbb..74f2b8259 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-28 Josh Triplett + + * mmap/i386/pc/mmap_helper.S: Set CF on return. + 2010-06-28 Colin Watson * util/grub-install.in: Add --debug-image= option. diff --git a/mmap/i386/pc/mmap_helper.S b/mmap/i386/pc/mmap_helper.S index 743954574..3302a9a15 100644 --- a/mmap/i386/pc/mmap_helper.S +++ b/mmap/i386/pc/mmap_helper.S @@ -59,7 +59,7 @@ LOCAL (e801): movw %bx, %dx pop %ds clc - iret + jmp LOCAL (iret_cf) LOCAL (h88): popf @@ -69,7 +69,7 @@ LOCAL (h88): movw DS (LOCAL (kbin16mb)), %ax pop %ds clc - iret + jmp LOCAL (iret_cf) LOCAL (e820): popf @@ -101,12 +101,18 @@ LOCAL (noclean): mov $0x534d4150, %eax pop %ds clc - iret + jmp LOCAL (iret_cf) LOCAL (errexit): mov $0x534d4150, %eax pop %ds - stc xor %bx, %bx + stc + +LOCAL (iret_cf): + push %bp + mov %sp, %bp + setc 6(%bp) + pop %bp iret VARIABLE(grub_machine_mmaphook_mmap_num) From bca58c7bb60e63970a6199111278d6fa927d8f82 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Jun 2010 11:32:50 +0100 Subject: [PATCH 370/503] * docs/grub.texi (Embedded configuration): New section (replacing old "Preset Menu" stub). (Images): New section. (configfile): Note that any menu entries defined in `file' are shown immediately. --- ChangeLog | 8 ++ docs/grub.texi | 210 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 216 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74f2b8259..b9f4544b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-28 Colin Watson + + * docs/grub.texi (Embedded configuration): New section (replacing + old "Preset Menu" stub). + (Images): New section. + (configfile): Note that any menu entries defined in `file' are shown + immediately. + 2010-06-28 Josh Triplett * mmap/i386/pc/mmap_helper.S: Set CF on return. diff --git a/docs/grub.texi b/docs/grub.texi index c1981633f..a7750992c 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -80,7 +80,6 @@ This edition documents version @value{VERSION}. * Network:: Downloading OS images from a network * Serial terminal:: Using GRUB via a serial line * Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys -* Preset Menu:: Embedding a configuration file into GRUB * Images:: GRUB image files * Filesystem:: Filesystem syntax and semantics * Interface:: The menu and the command-line @@ -805,6 +804,7 @@ need to write the whole thing by hand. @menu * Simple configuration:: Recommended for most users * Shell-like scripting:: For power users and developers +* Embedded configuration:: Embedding a configuration file into GRUB @end menu @@ -999,6 +999,74 @@ that file, making sure to leave at least the first two lines intact. @section Writing full configuration files directly +@node Embedded configuration +@section Embedding a configuration file into GRUB + +GRUB supports embedding a configuration file directly into the core image, +so that it is loaded before entering normal mode. This is useful, for +example, when it is not straightforward to find the real configuration file, +or when you need to debug problems with loading that file. +@command{grub-install} uses this feature when it is not using BIOS disk +functions or when installing to a different disk from the one containing +@file{/boot/grub}, in which case it needs to use the @command{search} +command (@pxref{search}) to find @file{/boot/grub}. + +To embed a configuration file, use the @option{-c} option to +@command{grub-mkimage}. The file is copied into the core image, so it may +reside anywhere on the file system, and may be removed after running +@command{grub-mkimage}. + +After the embedded configuration file (if any) is executed, GRUB will load +the @samp{normal} module, which will then read the real configuration file +from @file{$prefix/grub.cfg}. By this point, the @code{root} variable will +also have been set to the root device name. For example, @code{prefix} +might be set to @samp{(hd0,1)/boot/grub}, and @code{root} might be set to +@samp{hd0,1}. Thus, in most cases, the embedded configuration file only +needs to set the @code{prefix} and @code{root} variables, and then drop +through to GRUB's normal processing. A typical example of this might look +like this: + +@example +@group +search.fs_uuid 01234567-89ab-cdef-0123-456789abcdef root +set prefix=($root)/boot/grub +@end group +@end example + +(The @samp{search_fs_uuid} module must be included in the core image for this +example to work.) + +In more complex cases, it may be useful to read other configuration files +directly from the embedded configuration file. This allows such things as +reading files not called @file{grub.cfg}, or reading files from a directory +other than that where GRUB's loadable modules are installed. To do this, +include the @samp{configfile} and @samp{normal} modules in the core image, +and embed a configuration file that uses the @command{configfile} command to +load another file. The following example of this also requires the +@command{echo}, @command{search_label}, and @command{test} modules to be +included in the core image: + +@example +@group +search.fs_label grub root +if [ -e /boot/grub/example/test1.cfg ]; then + set prefix=($root)/boot/grub + configfile /boot/grub/example/test1.cfg +else + if [ -e /boot/grub/example/test2.cfg ]; then + set prefix=($root)/boot/grub + configfile /boot/grub/example/test2.cfg + else + echo "Could not find an example configuration file!" + fi +fi +@end group +@end example + +The embedded configuration file may not contain menu entries directly, but +may only read them from elsewhere using @command{configfile}. + + @node Network @chapter Booting GRUB from the network @@ -1122,6 +1190,7 @@ 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 Vendor power-on keys @chapter Using GRUB with vendor power-on keys Some laptop vendor provide an additional power-on button which boots another OS. @@ -1142,6 +1211,142 @@ Values known to GRUB team are: To take full advantage of this function install GRUB into MBR. + +@node Images +@chapter GRUB image files + +@c FIXME: parts of this section are specific to PC BIOS right now. + +GRUB consists of several images: a variety of bootstrap images for starting +GRUB in various ways, a kernel image, and a set of modules which are +combined with the kernel image to form a core image. Here is a short +overview of them. + +@table @file +@item boot.img +On PC BIOS systems, this image is the first part of GRUB to start. It is +written to a master boot record (MBR) or to the boot sector of a partition. +Because a PC boot sector is 512 bytes, the size of this image is exactly 512 +bytes. + +The sole function of @file{boot.img} is to read the first sector of the core +image from a local disk and jump to it. Because of the size restriction, +@file{boot.img} cannot understand any file system structure, so +@command{grub-setup} hardcodes the location of the first sector of the core +image into @file{boot.img} when installing GRUB. + +@item diskboot.img +This image is used as the first sector of the core image when booting from a +hard disk. It reads the rest of the core image into memory and starts the +kernel. Since file system handling is not yet available, it encodes the +location of the core image using a block list format. + +@item cdboot.img +This image is used as the first sector of the core image when booting from a +CD-ROM drive. It performs a similar function to @file{diskboot.img}. + +@item pxeboot.img +This image is used as the start of the core image when booting from the +network using PXE. @xref{Network}. + +@item lnxboot.img +This image may be placed at the start of the core image in order to make +GRUB look enough like a Linux kernel that it can be booted by LILO using an +@samp{image=} section. + +@item kernel.img +This image contains GRUB's basic run-time facilities: frameworks for device +and file handling, environment variables, the rescue mode command-line +parser, and so on. It is rarely used directly, but is built into all core +images. + +@item core.img +This is the core image of GRUB. It is built dynamically from the kernel +image and an arbitrary list of modules by the @command{grub-mkimage} +program. Usually, it contains enough modules to access @file{/boot/grub}, +and loads everything else (including menu handling, the ability to load +target operating systems, and so on) from the file system at run-time. The +modular design allows the core image to be kept small, since the areas of +disk where it must be installed are often as small as 32KB. + +On PC systems using the traditional MBR partition table format, the core +image is usually installed in the "MBR gap" between the master boot record +and the first partition, or sometimes it is installed in a file system and +read directly from that. The latter is not recommended because GRUB needs +to encode the location of all the core image sectors in @file{diskboot.img}, +and if the file system ever moves the core image around (as it is entitled +to do) then GRUB must be reinstalled; it also means that GRUB will not be +able to reliably find the core image if it resides on a different disk than +the one to which @file{boot.img} was installed. + +On PC systems using the more recent GUID Partition Table (GPT) format, the +core image should be installed to a BIOS Boot Partition. This may be +created by GNU Parted using a command such as the following: + +@example +# @kbd{parted /dev/@var{disk} set @var{partition-number} bios_grub on} +@end example + +@strong{Caution:} Be very careful which partition you select! When GRUB +finds a BIOS Boot Partition during installation, it will automatically +overwrite part of it. Make sure that the partition does not contain any +other data. + +@item *.mod +Everything else in GRUB resides in dynamically loadable modules. These are +often loaded automatically, or built into the core image if they are +essential, but may also be loaded manually using the @command{insmod} +command (@pxref{insmod}). +@end table + +@heading For GRUB Legacy users + +GRUB 2 has a different design from GRUB Legacy, and so correspondences with +the images it used cannot be exact. Nevertheless, GRUB Legacy users often +ask questions in the terms they are familiar with, and so here is a brief +guide to how GRUB 2's images relate to that. + +@table @file +@item stage1 +Stage 1 from GRUB Legacy was very similar to @file{boot.img} in GRUB 2, and +they serve the same function. + +@item *_stage1_5 +In GRUB Legacy, Stage 1.5's function was to include enough filesystem code +to allow the much larger Stage 2 to be read from an ordinary filesystem. In +this respect, its function was similar to @file{core.img} in GRUB 2. +However, @file{core.img} is much more capable than Stage 1.5 was; since it +offers a rescue shell, it is sometimes possible to recover manually in the +event that it is unable to load any other modules, for example if partition +numbers have changed. @file{core.img} is built in a more flexible way, +allowing GRUB 2 to support reading modules from advanced disk types such as +LVM and RAID. + +GRUB Legacy could run with only Stage 1 and Stage 2 in some limited +configurations, while GRUB 2 requires @file{core.img} and cannot work +without it. + +@item stage2 +GRUB 2 has no single Stage 2 image. Instead, it loads modules from +@file{/boot/grub} at run-time. + +@item stage2_eltorito +In GRUB 2, images for booting from CD-ROM drives are now constructed using +@file{cdboot.img} and @file{core.img}, making sure that the core image +contains the @samp{iso9660} module. It is usually best to use the +@command{grub-mkrescue} program for this. + +@item nbgrub +There is as yet no equivalent for @file{nbgrub} in GRUB 2; it was used by +Etherboot and some other network boot loaders. + +@item pxegrub +In GRUB 2, images for PXE network booting are now constructed using +@file{pxeboot.img} and @file{core.img}, making sure that the core image +contains the @samp{pxe} and @samp{pxecmd} modules. @xref{Network}. +@end table + + @node Filesystem @chapter Filesystem syntax and semantics @@ -1679,7 +1884,8 @@ If they are completely identical, nothing will be printed. @subsection configfile @deffn Command configfile file -Load @var{file} as a configuration file. +Load @var{file} as a configuration file. If @var{file} defines any menu +entries, then show a menu containing them immediately. @end deffn From 4045dee1b9eafeb912cb7056ea5c2067d688e5a2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Jun 2010 12:42:50 +0200 Subject: [PATCH 371/503] Use normal parser for menu entries. Reported by: Thomas Frauendorfer * include/grub/parser.h (grub_parser_execute): Don't export. * normal/menu.c (grub_menu_execute_entry_real): New function. (grub_menu_execute_entry): Use grub_menu_execute_entry_real. --- ChangeLog | 9 +++++++++ include/grub/parser.h | 2 +- normal/menu.c | 41 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b9f4544b3..bccc55dea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-06-28 Vladimir Serbinenko + + Use normal parser for menu entries. + Reported by: Thomas Frauendorfer + + * include/grub/parser.h (grub_parser_execute): Don't export. + * normal/menu.c (grub_menu_execute_entry_real): New function. + (grub_menu_execute_entry): Use grub_menu_execute_entry_real. + 2010-06-28 Colin Watson * docs/grub.texi (Embedded configuration): New section (replacing diff --git a/include/grub/parser.h b/include/grub/parser.h index 064f73fcb..de4da05ad 100644 --- a/include/grub/parser.h +++ b/include/grub/parser.h @@ -83,7 +83,7 @@ struct grub_parser }; typedef struct grub_parser *grub_parser_t; -grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source); +grub_err_t grub_parser_execute (char *source); grub_err_t grub_rescue_parse_line (char *line, grub_reader_getline_t getline); diff --git a/normal/menu.c b/normal/menu.c index 09c5fd1eb..f98cfed66 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -29,6 +29,7 @@ #include #include #include +#include /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ @@ -141,6 +142,44 @@ get_and_remove_first_entry_number (const char *name) return entry; } +static void +grub_menu_execute_entry_real (grub_menu_entry_t entry) +{ + const char *source; + + auto grub_err_t getline (char **line, int cont); + grub_err_t getline (char **line, int cont __attribute__ ((unused))) + { + const char *p; + + if (!source) + { + *line = 0; + return 0; + } + + p = grub_strchr (source, '\n'); + + if (p) + *line = grub_strndup (source, p - source); + else + *line = grub_strdup (source); + source = p ? p + 1 : 0; + return 0; + } + + source = entry->sourcecode; + + while (source) + { + char *line; + + getline (&line, 0); + grub_normal_parse_line (line, getline); + grub_free (line); + } +} + /* Run a menu entry. */ void grub_menu_execute_entry(grub_menu_entry_t entry) @@ -159,7 +198,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry) grub_env_set ("chosen", entry->title); - grub_parser_execute ((char *) entry->sourcecode); + grub_menu_execute_entry_real (entry); if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) /* Implicit execution of boot, only if something is loaded. */ From 20bc84a6ff0020c91876bc5b0a1c3deefa96fb1c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Jun 2010 12:02:39 +0100 Subject: [PATCH 372/503] * docs/grub.texi (Device map): New section. (Themes): New section (stub). * Makefile.in (docs/grub.info): The info documentation now builds without errors. Make sure it stays that way. --- ChangeLog | 7 +++++++ Makefile.in | 3 +-- docs/grub.texi | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bccc55dea..c7d301dcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-28 Colin Watson + + * docs/grub.texi (Device map): New section. + (Themes): New section (stub). + * Makefile.in (docs/grub.info): The info documentation now builds + without errors. Make sure it stays that way. + 2010-06-28 Vladimir Serbinenko Use normal parser for menu entries. diff --git a/Makefile.in b/Makefile.in index b9b7f3d08..b6b8f0d43 100644 --- a/Makefile.in +++ b/Makefile.in @@ -247,10 +247,9 @@ docs/stamp-vti: docs/grub.texi configure.ac -@rm -f vti.tmp @cp $(builddir)/docs/version.texi $@ -# Use --force until such time as the documentation is cleaned up. docs/grub.info: docs/grub.texi docs/version.texi docs/fdl.texi $(MKDIR_P) docs - -$(MAKEINFO) -P $(builddir)/docs --no-split --force $< -o $@ + $(MAKEINFO) -P $(builddir)/docs --no-split $< -o $@ ifeq (, $(FONT_SOURCE)) else diff --git a/docs/grub.texi b/docs/grub.texi index a7750992c..38b046814 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -470,6 +470,7 @@ the @dfn{boot directory}. @menu * Installing GRUB using grub-install:: * Making a GRUB bootable CD-ROM:: +* Device map:: @end menu @@ -614,6 +615,50 @@ 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 Device map +@section The map between BIOS drives and OS devices + +The @command{grub-mkdevicemap} program can be used to create the @dfn{device +map file}. It is often run automatically by tools such as +@command{grub-install} if the device map file does not already exist. The +file name @file{/boot/grub/device.map} is preferred. + +If the device map file exists, the GRUB utilities (@command{grub-probe}, +@command{grub-setup}, etc.) read 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. + +Historically, the device map file was used because GRUB device names had to +be used in the configuration file, and they were derived from BIOS drive +numbers. The map between BIOS drives and OS devices cannot always be +guessed correctly: for example, GRUB will get the order wrong if you +exchange the boot sequence between IDE and SCSI in your BIOS. + +Unfortunately, even OS device names are not always stable. Modern versions +of the Linux kernel may probe drives in a different order from boot to boot, +and the prefix (@file{/dev/hd*} versus @file{/dev/sd*}) may change depending +on the driver subsystem in use. As a result, the device map file required +frequent editing on some systems. + +GRUB avoids this problem nowadays by using UUIDs or file system labels when +generating @file{grub.cfg}, and we advise that you do the same for any +custom menu entries you write. If the device map file does not exist, then +the GRUB utilities will assume a temporary device map on the fly. This is +often good enough, particularly in the common case of single-disk systems. + +However, the device map file is not entirely obsolete yet, and there are +still some situations that require it to exist. If necessary, you may edit +the file if @command{grub-mkdevicemap} makes a mistake. You can put any +comments in the file if needed, as the GRUB utilities assume that a line is +just a comment if the first character is @samp{#}. + + @node Booting @chapter Booting @@ -805,6 +850,7 @@ need to write the whole thing by hand. * Simple configuration:: Recommended for most users * Shell-like scripting:: For power users and developers * Embedded configuration:: Embedding a configuration file into GRUB +* Themes:: Graphical menu themes @end menu @@ -1067,6 +1113,10 @@ The embedded configuration file may not contain menu entries directly, but may only read them from elsewhere using @command{configfile}. +@node Themes +@section Graphical menu themes + + @node Network @chapter Booting GRUB from the network From d500ed127e737cf1dd40e54e79fa0fe4f160da5b Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 28 Jun 2010 23:52:03 +0200 Subject: [PATCH 373/503] 2010-06-28 Robert Millan * util/grub-mkconfig.in: Export `GRUB_BADRAM' variable. * util/grub.d/00_header.in: When `GRUB_BADRAM' is set, issue badram command using ${GRUB_BADRAM} as parameter. --- ChangeLog | 6 ++++++ util/grub-mkconfig.in | 5 +++-- util/grub.d/00_header.in | 9 +++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c7d301dcc..59c94a44e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-28 Robert Millan + + * util/grub-mkconfig.in: Export `GRUB_BADRAM' variable. + * util/grub.d/00_header.in: When `GRUB_BADRAM' is set, issue badram + command using ${GRUB_BADRAM} as parameter. + 2010-06-28 Colin Watson * docs/grub.texi (Device map): New section. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 5548da4da..e417b4352 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -1,7 +1,7 @@ #! /bin/sh -e # Generate grub.cfg by inspecting /boot contents. -# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -274,7 +274,8 @@ export GRUB_DEFAULT \ GRUB_GFXPAYLOAD_LINUX \ GRUB_DISABLE_OS_PROBER \ GRUB_INIT_TUNE \ - GRUB_SAVEDEFAULT + GRUB_SAVEDEFAULT \ + GRUB_BADRAM if test "x${grub_cfg}" != "x"; then rm -f ${grub_cfg}.new diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 8040a7c9b..8186ffd2d 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -255,8 +255,9 @@ fi # Play an initial tune if [ "x${GRUB_INIT_TUNE}" != "x" ] ; then - cat << EOF -insmod play -play ${GRUB_INIT_TUNE} -EOF + echo "play ${GRUB_INIT_TUNE}" +fi + +if [ "x${GRUB_BADRAM}" != "x" ] ; then + echo "badram ${GRUB_BADRAM}" fi From dccaf99d10e3c8cfbca40b2a914893cffa6ff6f0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 29 Jun 2010 00:48:53 +0200 Subject: [PATCH 374/503] 2010-06-29 Robert Millan * docs/grub.texi (Simple configuration): Document ${GRUB_BADRAM}. (Command-line and menu entry commands): Document `badram' command. --- ChangeLog | 5 +++++ docs/grub.texi | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/ChangeLog b/ChangeLog index 59c94a44e..46c0ee188 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-29 Robert Millan + + * docs/grub.texi (Simple configuration): Document ${GRUB_BADRAM}. + (Command-line and menu entry commands): Document `badram' command. + 2010-06-28 Robert Millan * util/grub-mkconfig.in: Export `GRUB_BADRAM' variable. diff --git a/docs/grub.texi b/docs/grub.texi index 38b046814..ba5b43a1c 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1032,6 +1032,11 @@ for them. Set this option to @samp{true} to disable this. Play a tune on the speaker when GRUB starts. This is particularly useful for users unable to see the screen. The value of this option is passed directly to @ref{play}. + +@item GRUB_BADRAM +If this option is set, GRUB will issue a @ref{badram} command to filter +out specified regions of RAM. + @end table For more detailed customisation of @command{grub-mkconfig}'s output, you may @@ -1804,6 +1809,7 @@ you forget a command, you can run the command @command{help} @menu * acpi:: Load ACPI tables +* badram:: Filter out bad regions of RAM * blocklist:: Print a block list * boot:: Start up your operating system * cat:: Show the contents of a file @@ -1857,6 +1863,27 @@ Normally, this command will replace the Root System Description Pointer GRUB, but may be used by GRUB's EFI emulation. @end deffn +@node badram +@subsection badram + +@deffn Command badram addr,mask[,addr,mask...] +Filter out bad RAM. +@end deffn + +This command notifies the memory manager that specified regions of +RAM ought to be filtered out (usually, because they're damaged). This +remains in effect after a payload kernel has been loaded by GRUB, as +long as the loaded kernel obtains its memory map from GRUB. Kernels that +support this include Linux, GNU Mach, the kernel of FreeBSD and Multiboot +kernels in general. + +Syntax is the same as provided by the @uref{http://www.memtest.org/, +Memtest86+ utility}: a list of address/mask pairs. Given a page-aligned +address and a base address / mask pair, if all the bits of the page-aligned +address that are enabled by the mask match with the base address, it means +this page is to be filtered. This syntax makes it easy to represent patterns +that are often result of memory damage, due to physical distribution of memory +cells. @node blocklist @subsection blocklist From 1ba9b889469abd684e6f6e9519a17565dcf0e394 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 29 Jun 2010 16:15:46 +0100 Subject: [PATCH 375/503] * commands/cat.c (grub_cmd_cat): Fix buffer overrun if '\r' is the last character in the buffer. Reported by: Vladimir Serbinenko. --- ChangeLog | 6 ++++++ commands/cat.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 46c0ee188..54880f44f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-29 Colin Watson + + * commands/cat.c (grub_cmd_cat): Fix buffer overrun if '\r' is the + last character in the buffer. + Reported by: Vladimir Serbinenko. + 2010-06-29 Robert Millan * docs/grub.texi (Simple configuration): Document ${GRUB_BADRAM}. diff --git a/commands/cat.c b/commands/cat.c index 4c0e19bc2..289cf7352 100644 --- a/commands/cat.c +++ b/commands/cat.c @@ -63,7 +63,7 @@ grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args) if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') grub_putchar (c); - else if (dos && c == '\r' && buf[i + 1] == '\n') + else if (dos && c == '\r' && i + 1 < size && buf[i + 1] == '\n') { grub_putchar ('\n'); i++; From 1246efeb8bdf47d8d2dde6349973d7686973b0de Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 29 Jun 2010 16:20:49 +0100 Subject: [PATCH 376/503] * util/grub-mkconfig.in: Use 'set -e' rather than '#! /bin/sh -e', to avoid accidents when debugging with 'sh -x'. * util/grub-mkrescue.in: Likewise. * util/grub.d/00_header.in: Likewise. * util/grub.d/10_hurd.in: Likewise. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_linux.in: Likewise. * util/grub.d/10_netbsd.in: Likewise. * util/grub.d/10_windows.in: Likewise. * util/grub.d/20_linux_xen.in: Likewise. * util/grub.d/30_os-prober.in: Likewise. * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. --- ChangeLog | 15 +++++++++++++++ util/grub-mkconfig.in | 3 ++- util/grub-mkrescue.in | 3 ++- util/grub.d/00_header.in | 3 ++- util/grub.d/10_hurd.in | 3 ++- util/grub.d/10_kfreebsd.in | 3 ++- util/grub.d/10_linux.in | 3 ++- util/grub.d/10_netbsd.in | 3 ++- util/grub.d/10_windows.in | 3 ++- util/grub.d/20_linux_xen.in | 3 ++- util/grub.d/30_os-prober.in | 3 ++- util/powerpc/ieee1275/grub-mkrescue.in | 3 ++- 12 files changed, 37 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 54880f44f..f5988e08c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-06-29 Colin Watson + + * util/grub-mkconfig.in: Use 'set -e' rather than '#! /bin/sh -e', + to avoid accidents when debugging with 'sh -x'. + * util/grub-mkrescue.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/10_netbsd.in: Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + * util/grub.d/30_os-prober.in: Likewise. + * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. + 2010-06-29 Colin Watson * commands/cat.c (grub_cmd_cat): Fix buffer overrun if '\r' is the diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index e417b4352..828b54bce 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # Generate grub.cfg by inspecting /boot contents. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 36cce31ec..4a16558e4 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # Make GRUB rescue image # Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 8186ffd2d..553369e37 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index e446f10e8..350eb30a8 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index f63421617..9915abdf1 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 9e1450f51..57bc1eebc 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index 7e5fb34ad..1a8c4eb36 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 7d221eac9..fd068dd2d 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 9a0136a76..8612c96b0 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 90e2e3d92..601663dcc 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index 4ef26f616..aefedff3f 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -1,4 +1,5 @@ -#! /bin/sh -e +#! /bin/sh +set -e # Make GRUB rescue image # Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. From ff4a70d2919ccadb9dc12ebde2628c01b8c21ca0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Jun 2010 13:36:58 +0100 Subject: [PATCH 377/503] * Makefile.in (install-local): Temporarily prepend $(builddir) to PATH when running help2man and then run it on the unadorned executable names, rather than passing $(builddir)/* paths to help2man. This avoids the build directory ending up in generated manual pages. --- ChangeLog | 8 ++++++++ Makefile.in | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index f5988e08c..04a0dc082 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-30 Colin Watson + + * Makefile.in (install-local): Temporarily prepend $(builddir) to + PATH when running help2man and then run it on the unadorned + executable names, rather than passing $(builddir)/* paths to + help2man. This avoids the build directory ending up in generated + manual pages. + 2010-06-29 Colin Watson * util/grub-mkconfig.in: Use 'set -e' rather than '#! /bin/sh -e', diff --git a/Makefile.in b/Makefile.in index b6b8f0d43..a4b4ed45f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -322,26 +322,26 @@ install-local: all 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 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + PATH="$(builddir):$$PATH" $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $$file; \ done $(SHELL) $(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 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + PATH="$(builddir):$$PATH" $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $$file; \ 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 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + PATH="$(builddir):$$PATH" $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $$file; \ 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 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + PATH="$(builddir):$$PATH" $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $$file; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \ From b79889ba767ca02de3a7db14ef32a2e9c11169a6 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 1 Jul 2010 10:52:23 +0200 Subject: [PATCH 378/503] 2010-07-01 Robert Millan * kern/emu/hostdisk.c (convert_system_partition_to_system_disk): Support 'p' as partition separator on kernel of FreeBSD (used with GPT labels). (grub_util_biosdisk_get_grub_dev): Likewise. --- ChangeLog | 7 +++++++ kern/emu/hostdisk.c | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70572f940..f21d94425 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-07-01 Robert Millan + + * kern/emu/hostdisk.c (convert_system_partition_to_system_disk): + Support 'p' as partition separator on kernel of FreeBSD (used + with GPT labels). + (grub_util_biosdisk_get_grub_dev): Likewise. + 2010-07-01 Vladimir Serbinenko Yeeloong firmware port. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index bc37e9949..2cdf449e2 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -1260,7 +1260,7 @@ devmapper_out: for (p = path + 5; *p; ++p) if (grub_isdigit(*p)) { - p = strchr (p, 's'); + p = strpbrk (p, "sp"); if (p) *p = '\0'; break; @@ -1507,7 +1507,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) - /* FreeBSD uses "/dev/[a-z]+[0-9]+(s[0-9]+[a-z]?)?". */ + /* FreeBSD uses "/dev/[a-z]+[0-9]+([sp][0-9]+[a-z]?)?". */ { int dos_part = -1; int bsd_part = -1; @@ -1521,7 +1521,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) for (p = os_dev + 5; *p; ++p) if (grub_isdigit(*p)) { - p = strchr (p, 's'); /* msdos or apple (or ... ?) partition map */ + p = strpbrk (p, "sp"); /* msdos or apple (or ... ?) partition map */ if (p) { p++; From 5944958c61a4b8aa11162d01ea61462d02db7ac4 Mon Sep 17 00:00:00 2001 From: Sean Finney Date: Thu, 1 Jul 2010 23:19:11 +0200 Subject: [PATCH 379/503] * disk/lvm.c (grub_lvm_scan_device): Skip snapshots. 2010-07-01 Vladimir Serbinenko * disk/lvm.c (grub_lvm_checkvalue): New function. (grub_lvm_check_flag): Likewise. Also-By: Vladimir Serbinenko --- ChangeLog | 9 +++++++ disk/lvm.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/ChangeLog b/ChangeLog index f21d94425..341e122f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-07-01 Sean Finney + + * disk/lvm.c (grub_lvm_scan_device): Skip snapshots. + +2010-07-01 Vladimir Serbinenko + + * disk/lvm.c (grub_lvm_checkvalue): New function. + (grub_lvm_check_flag): Likewise. + 2010-07-01 Robert Millan * kern/emu/hostdisk.c (convert_system_partition_to_system_disk): diff --git a/disk/lvm.c b/disk/lvm.c index 7dde40920..71860e853 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -45,6 +45,52 @@ grub_lvm_getvalue (char **p, char *str) return grub_strtoul (*p, NULL, 10); } +static int +grub_lvm_checkvalue (char **p, char *str, char *tmpl) +{ + int tmpllen = grub_strlen (tmpl); + *p = grub_strstr (*p, str); + if (! *p) + return 0; + *p += grub_strlen (str); + if (**p != '"') + return 0; + return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"'); +} + +static int +grub_lvm_check_flag (char *p, char *str, char *flag) +{ + int len_str = grub_strlen (str), len_flag = grub_strlen (flag); + while (1) + { + char *q; + p = grub_strstr (p, str); + if (! p) + return 0; + p += len_str; + if (grub_memcmp (p, " = [", sizeof (" = [") - 1) != 0) + continue; + q = p + sizeof (" = [") - 1; + while (1) + { + while (grub_isspace (*q)) + q++; + if (*q != '"') + return 0; + q++; + if (grub_memcmp (q, flag, len_flag) == 0 && q[len_flag] == '"') + return 1; + while (*q != '"') + q++; + q++; + if (*q == ']') + return 0; + q++; + } + } +} + static int grub_lvm_iterate (int (*hook) (const char *name)) { @@ -421,6 +467,7 @@ grub_lvm_scan_device (const char *name) while (1) { int s; + int skip_lv = 0; struct grub_lvm_lv *lv; struct grub_lvm_segment *seg; @@ -445,6 +492,12 @@ grub_lvm_scan_device (const char *name) lv->size = 0; + if (!grub_lvm_check_flag (p, "status", "VISIBLE")) + { + skip_lv = 1; + goto lv_parsed; + } + lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); if (p == NULL) goto lvs_fail; @@ -465,6 +518,14 @@ grub_lvm_scan_device (const char *name) seg->extent_count = grub_lvm_getvalue (&p, "extent_count = "); if (p == NULL) goto lvs_segment_fail; + + if (grub_lvm_checkvalue (&p, "type = ", "snapshot")) + { + /* Found a snapshot, give up and move on. */ + skip_lv = 1; + break; + } + seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); if (p == NULL) goto lvs_segment_fail; @@ -531,12 +592,20 @@ grub_lvm_scan_device (const char *name) goto fail4; } + lv_parsed: if (p != NULL) p = grub_strchr (p, '}'); if (p == NULL) goto lvs_fail; p += 3; + if (skip_lv) + { + grub_free (lv->name); + grub_free (lv); + continue; + } + lv->number = lv_count++; lv->vg = vg; lv->next = vg->lvs; From 105a2e8c6638928330bcf5dfc6063474ac4ceb4a Mon Sep 17 00:00:00 2001 From: Sean Finney Date: Thu, 1 Jul 2010 23:24:21 +0200 Subject: [PATCH 380/503] * util/grub.d/10_linux.in: Don't use UUID for LVM root. --- ChangeLog | 4 ++++ util/grub.d/10_linux.in | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 341e122f3..e60f1076c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-01 Sean Finney + + * util/grub.d/10_linux.in: Don't use UUID for LVM root. + 2010-07-01 Sean Finney * disk/lvm.c (grub_lvm_scan_device): Skip snapshots. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 57bc1eebc..2e0143df2 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -44,7 +44,8 @@ case ${GRUB_DEVICE} in esac if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ - || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then + || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ + || [ "x`grub-probe -t abstraction --device ${GRUB_DEVICE}`" = "xlvm" ] ; then LINUX_ROOT_DEVICE=${GRUB_DEVICE} else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} From b0c4f9564263a169e4d9061e40a45722ea70a53d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 1 Jul 2010 23:35:45 +0200 Subject: [PATCH 381/503] * util/grub-mkrescue.in: Avoid module duplication. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e60f1076c..a03294df6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-01 Vladimir Serbinenko + + * util/grub-mkrescue.in: Avoid module duplication. + 2010-07-01 Sean Finney * util/grub.d/10_linux.in: Don't use UUID for LVM root. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4a16558e4..3bfbbddd4 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -200,13 +200,12 @@ make_image () memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${memdisk_dir}/boot/grub - modules="$(cat ${source_directory}/partmap.lst) ${modules}" cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${platform} source \$prefix/grub.cfg EOF - (for i in ${modules} ; do + (for i in $(cat ${source_directory}/partmap.lst) ${modules} ; do echo "insmod $i" done ; \ echo "source /boot/grub/grub.cfg") \ @@ -273,8 +272,7 @@ if test -e "${pc_dir}" ; then rm -f ${core_img} - modules="$(cat ${pc_dir}/partmap.lst) ${modules}" - (for i in ${modules} ; do + (for i in $(cat ${pc_dir}/partmap.lst) ${modules} ; do echo "insmod $i" done ; \ echo "source /boot/grub/grub.cfg") \ From 48f27e87fcbdae34ca056b9c14223a6b5e68f0aa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 00:40:37 +0200 Subject: [PATCH 382/503] * loader/multiboot.c (grub_multiboot_boot) [GRUB_USE_MULTIBOOT2]: Properly align mbi. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ loader/multiboot.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index a03294df6..ba99ab2e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Vladimir Serbinenko + + * loader/multiboot.c (grub_multiboot_boot) [GRUB_USE_MULTIBOOT2]: + Properly align mbi. + Reported by: Seth Goldberg. + 2010-07-01 Vladimir Serbinenko * util/grub-mkrescue.in: Avoid module duplication. diff --git a/loader/multiboot.c b/loader/multiboot.c index 592289c45..77a732838 100644 --- a/loader/multiboot.c +++ b/loader/multiboot.c @@ -136,8 +136,14 @@ grub_multiboot_boot (void) grub_multiboot_alloc_mbi = mbi_size; } +#ifdef GRUB_USE_MULTIBOOT2 + state.MULTIBOOT_MBI_REGISTER = ALIGN_UP (grub_multiboot_payload_dest + + grub_multiboot_pure_size, + MULTIBOOT_TAG_ALIGN); +#else state.MULTIBOOT_MBI_REGISTER = grub_multiboot_payload_dest + grub_multiboot_pure_size; +#endif err = grub_multiboot_make_mbi (grub_multiboot_payload_orig, grub_multiboot_payload_dest, grub_multiboot_pure_size, mbi_size); From d9a0c9413e81d3c0affc6383693bdd28dc863a5c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 02:43:09 +0200 Subject: [PATCH 383/503] * kern/efi/init.c (grub_efi_init): Disable watchdog. Tested by: Seth Goldberg. --- ChangeLog | 5 +++++ kern/efi/init.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index ba99ab2e2..d456f1fca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-02 Vladimir Serbinenko + + * kern/efi/init.c (grub_efi_init): Disable watchdog. + Tested by: Seth Goldberg. + 2010-07-02 Vladimir Serbinenko * loader/multiboot.c (grub_multiboot_boot) [GRUB_USE_MULTIBOOT2]: diff --git a/kern/efi/init.c b/kern/efi/init.c index b79084a6a..d8a85eddf 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -36,6 +36,9 @@ grub_efi_init (void) /* Initialize the memory management system. */ grub_efi_mm_init (); + efi_call_3 (grub_efi_system_table->boot_services->set_watchdog_timer, + 0, 0, 0); + grub_efidisk_init (); } From 1c4827beff3f5421c1440b280c8b8b82199ddf86 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 02:47:10 +0200 Subject: [PATCH 384/503] * partmap/gpt.c (MAX_SECTOR_LOG): New definition. (gpt_partition_map_iterate): Support non-512B sectors. --- ChangeLog | 5 +++++ partmap/gpt.c | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index d456f1fca..3eff5f884 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-02 Vladimir Serbinenko + + * partmap/gpt.c (MAX_SECTOR_LOG): New definition. + (gpt_partition_map_iterate): Support non-512B sectors. + 2010-07-02 Vladimir Serbinenko * kern/efi/init.c (grub_efi_init): Disable watchdog. diff --git a/partmap/gpt.c b/partmap/gpt.c index 9dd88bec1..0dd670cce 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -32,6 +32,9 @@ static grub_uint8_t grub_gpt_magic[8] = static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; +/* 512 << 7 = 65536 byte sectors. */ +#define MAX_SECTOR_LOG 7 + static struct grub_partition_map grub_gpt_partition_map; @@ -48,6 +51,7 @@ gpt_partition_map_iterate (grub_disk_t disk, grub_uint64_t entries; unsigned int i; int last_offset = 0; + int sector_log = 0; /* Read the protective MBR. */ if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr)) @@ -62,15 +66,20 @@ gpt_partition_map_iterate (grub_disk_t disk, return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found"); /* Read the GPT header. */ - if (grub_disk_read (disk, 1, 0, sizeof (gpt), &gpt)) - return grub_errno; + for (sector_log = 0; sector_log < MAX_SECTOR_LOG; sector_log++) + { + if (grub_disk_read (disk, 1 << sector_log, 0, sizeof (gpt), &gpt)) + return grub_errno; - if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic))) + if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)) == 0) + break; + } + if (sector_log == MAX_SECTOR_LOG) 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); + entries = grub_le_to_cpu64 (gpt.partitions) << sector_log; for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++) { if (grub_disk_read (disk, entries, last_offset, @@ -81,9 +90,9 @@ gpt_partition_map_iterate (grub_disk_t disk, 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.start = grub_le_to_cpu64 (entry.start) << sector_log; part.len = (grub_le_to_cpu64 (entry.end) - - grub_le_to_cpu64 (entry.start) + 1); + - grub_le_to_cpu64 (entry.start) + 1) << sector_log; part.offset = entries; part.number = i; part.index = last_offset; From 8d4a2fec0dc785b51c3d45a40cfa5b046ede9875 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 2 Jul 2010 10:50:04 +0100 Subject: [PATCH 385/503] * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Sometimes grub.d/README accidentally ends up executable for one reason or another. Ignore it. --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 1 + 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3eff5f884..57209d1f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Colin Watson + + * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Sometimes + grub.d/README accidentally ends up executable for one reason or + another. Ignore it. + 2010-07-02 Vladimir Serbinenko * partmap/gpt.c (MAX_SECTOR_LOG): New definition. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 14ea1842f..bdd2b8c6f 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -128,6 +128,7 @@ grub_file_is_not_garbage () if test -f "$1" ; then case "$1" in *.dpkg-*) return 1 ;; # debian dpkg + README*) return 1 ;; # documentation esac else return 1 From e3c8cd3719b2ce245be0be4ce2542deb39d18617 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 2 Jul 2010 12:13:48 +0100 Subject: [PATCH 386/503] * docs/grub.texi (Changes from GRUB Legacy): New section. (Future): Fix typo. --- ChangeLog | 5 ++++ docs/grub.texi | 71 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 57209d1f0..badca6588 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-02 Colin Watson + + * docs/grub.texi (Changes from GRUB Legacy): New section. + (Future): Fix typo. + 2010-07-02 Colin Watson * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Sometimes diff --git a/docs/grub.texi b/docs/grub.texi index ba5b43a1c..cf73a2d38 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -106,6 +106,7 @@ This edition documents version @value{VERSION}. * Overview:: What exactly GRUB is and how to use it * History:: From maggot to house fly * Features:: GRUB features +* Changes from GRUB Legacy:: Differences from previous versions * Role of a boot loader:: The role of a boot loader @end menu @@ -190,6 +191,74 @@ extents, and by the end of 2009 multiple major distributions were installing it by default. +@node Changes from GRUB Legacy +@section Differences from previous versions + +GRUB 2 is a rewrite of GRUB (@pxref{History}), although it shares many +characteristics with the previous version, now known as GRUB Legacy. Users +of GRUB Legacy may need some guidance to find their way around this new +version. + +@itemize @bullet +@item +The configuration file has a new name (@file{grub.cfg} rather than +@file{menu.lst} or @file{grub.conf}), new syntax (@pxref{Configuration}) and +many new commands (@pxref{Commands}). Configuration cannot be copied over +directly, although most GRUB Legacy users should not find the syntax too +surprising. + +@item +@file{grub.cfg} is typically automatically generated by +@command{grub-mkconfig} (@pxref{Simple configuration}). This makes it +easier to handle versioned kernel upgrades. + +@item +Partition numbers in GRUB device names now start at 1, not 0 (@pxref{Naming +convention}). + +@item +The configuration file is now written in something closer to a full +scripting language: variables, conditionals, and loops are available. + +@item +A small amount of persistent storage is available across reboots, using the +@command{save_env} and @command{load_env} commands in GRUB and the +@command{grub-editenv} utility. + +@item +GRUB 2 has more reliable ways to find its own files and those of target +kernels on multiple-disk systems, and has commands (@pxref{search}) to find +devices using file system labels or Universally Unique Identifiers (UUIDs). + +@item +GRUB 2 is available for several other types of system in addition to the PC +BIOS systems supported by GRUB Legacy: PC EFI, PC coreboot, PowerPC, SPARC, +and MIPS Lemote Yeeloong are all supported. + +@item +Many more file systems are supported, including but not limited to ext4, +HFS+, and NTFS. + +@item +GRUB 2 can read files directly from LVM and RAID devices. + +@item +A graphical terminal and a graphical menu system are available. + +@item +GRUB 2's interface can be translated, including menu entry names. + +@item +The image files (@pxref{Images}) that make up GRUB have been reorganised; +Stage 1, Stage 1.5, and Stage 2 are no more. + +@item +GRUB 2 puts many facilities in dynamically loaded modules, allowing the core +image to be smaller, and allowing the core image to be built in more +flexible ways. +@end itemize + + @node Features @section GRUB features @@ -2655,7 +2724,7 @@ Once we get your report, we will try to fix the bugs. We started the next generation of GRUB, GRUB 2. GRUB 2 includes 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 +nice features. 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}. From 507736c87c49712ac618169d17a659bd6c25eecc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 2 Jul 2010 12:32:05 +0100 Subject: [PATCH 387/503] * util/grub-mkconfig_lib.in (uses_abstraction): New function. * util/grub.d/10_linux.in: Use it to check for LVM, so that LVM-on-RAID is handled correctly. --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 12 ++++++++++++ util/grub.d/10_linux.in | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index badca6588..fc139b4ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Colin Watson + + * util/grub-mkconfig_lib.in (uses_abstraction): New function. + * util/grub.d/10_linux.in: Use it to check for LVM, so that + LVM-on-RAID is handled correctly. + 2010-07-02 Colin Watson * docs/grub.texi (Changes from GRUB Legacy): New section. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index bdd2b8c6f..9a77d1bdf 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -190,3 +190,15 @@ version_find_latest () gettext_quoted () { $gettext "$@" | sed "s/'/'\\\\''/g" } + +uses_abstraction () { + device=$1 + + abstraction="`${grub_probe} --device ${device} --target=abstraction`" + for module in ${abstraction}; do + if test "x${module}" = "x$2"; then + return 0 + fi + done + return 1 +} diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 2e0143df2..14b85c7f1 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -45,7 +45,7 @@ esac if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ - || [ "x`grub-probe -t abstraction --device ${GRUB_DEVICE}`" = "xlvm" ] ; then + || uses_abstraction "${GRUB_DEVICE}" lvm; then LINUX_ROOT_DEVICE=${GRUB_DEVICE} else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} From 47695765a475d114590f94fadcb8cc55acac3824 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 2 Jul 2010 13:42:18 +0100 Subject: [PATCH 388/503] * kern/efi/init.c (grub_efi_init): set_watchdog_timer takes four arguments, not three. --- ChangeLog | 5 +++++ kern/efi/init.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fc139b4ca..a8c5b4503 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-02 Colin Watson + + * kern/efi/init.c (grub_efi_init): set_watchdog_timer takes four + arguments, not three. + 2010-07-02 Colin Watson * util/grub-mkconfig_lib.in (uses_abstraction): New function. diff --git a/kern/efi/init.c b/kern/efi/init.c index d8a85eddf..c124aa292 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -36,8 +36,8 @@ grub_efi_init (void) /* Initialize the memory management system. */ grub_efi_mm_init (); - efi_call_3 (grub_efi_system_table->boot_services->set_watchdog_timer, - 0, 0, 0); + efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer, + 0, 0, 0, NULL); grub_efidisk_init (); } From e03ed6c1eebe42172070944d4d611cf58626cdd1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 2 Jul 2010 13:47:14 +0100 Subject: [PATCH 389/503] * include/grub/misc.h (grub_reboot): Declare as noreturn. * kern/efi/efi.c (grub_reboot): Don't return, even if reset_system fails. (grub_halt): Likewise. * kern/ieee1275/openfw.c (grub_reboot): Don't return, even if reset-all fails. (grub_halt): Don't return, even if all of shut-down, power-off, and poweroff fail. --- ChangeLog | 11 +++++++++++ include/grub/misc.h | 2 +- kern/efi/efi.c | 2 ++ kern/ieee1275/openfw.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a8c5b4503..e1e7ef00d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-07-02 Colin Watson + + * include/grub/misc.h (grub_reboot): Declare as noreturn. + * kern/efi/efi.c (grub_reboot): Don't return, even if reset_system + fails. + (grub_halt): Likewise. + * kern/ieee1275/openfw.c (grub_reboot): Don't return, even if + reset-all fails. + (grub_halt): Don't return, even if all of shut-down, power-off, and + poweroff fail. + 2010-07-02 Colin Watson * kern/efi/init.c (grub_efi_init): set_watchdog_timer takes four diff --git a/include/grub/misc.h b/include/grub/misc.h index a1b753250..909e85b5f 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -298,7 +298,7 @@ grub_div_roundup (unsigned int x, unsigned int y) } /* Reboot the machine. */ -void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_reboot) (void) __attribute__ ((noreturn)); #ifdef GRUB_MACHINE_PCBIOS /* Halt the system, using APM if possible. If NO_APM is true, don't diff --git a/kern/efi/efi.c b/kern/efi/efi.c index d8b225535..126e40901 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -170,6 +170,7 @@ 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); + for (;;) ; } #endif @@ -179,6 +180,7 @@ 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); + for (;;) ; } int diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 5693f3be0..75767d13c 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -420,6 +420,7 @@ void grub_reboot (void) { grub_ieee1275_interpret ("reset-all", 0); + for (;;) ; } #endif @@ -431,4 +432,5 @@ grub_halt (void) grub_ieee1275_interpret ("shut-down", 0); grub_ieee1275_interpret ("power-off", 0); grub_ieee1275_interpret ("poweroff", 0); + for (;;) ; } From 2bdb2892b339fa253e1ca8016ebef52b477ab65d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 2 Jul 2010 17:11:42 +0100 Subject: [PATCH 390/503] * util/deviceiter.c (grub_util_iterate_devices): Skip device-mapper devices when iterating over /dev/disk/by-id; they will be handled later if appropriate, which they aren't always (e.g. LVM). --- ChangeLog | 6 ++++++ util/deviceiter.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index e1e7ef00d..dcdb3a7ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Colin Watson + + * util/deviceiter.c (grub_util_iterate_devices): Skip device-mapper + devices when iterating over /dev/disk/by-id; they will be handled + later if appropriate, which they aren't always (e.g. LVM). + 2010-07-02 Colin Watson * include/grub/misc.h (grub_reboot): Declare as noreturn. diff --git a/util/deviceiter.c b/util/deviceiter.c index e3a0ab76d..64d1cae87 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -519,6 +519,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), /* Skip partition entries. */ if (strstr (entry->d_name, "-part")) continue; + /* Skip device-mapper entries; we'll handle the ones we want + later. */ + if (strncmp (entry->d_name, "dm-", sizeof ("dm-") - 1) == 0) + continue; if (names_len >= names_max) { names_max *= 2; From 919e37b0aca8d50578bf043c089056bb5eecdcdf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 18:20:48 +0200 Subject: [PATCH 391/503] Inline setcolorstate and move grub_Cls out of kernel.img --- commands/minicmd.c | 15 --------------- include/grub/term.h | 12 ++++++++++-- kern/term.c | 26 -------------------------- normal/main.c | 18 ++++++++++++++++++ normal/term.c | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 43 deletions(-) diff --git a/commands/minicmd.c b/commands/minicmd.c index 4d0ae19b4..25bda6d23 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -336,19 +336,8 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)), return 0; } -/* clear */ -static grub_err_t -grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - grub_cls (); - return 0; -} - static grub_command_t cmd_cat, cmd_help, cmd_root; static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit; -static grub_command_t cmd_clear; GRUB_MOD_INIT(minicmd) { @@ -373,9 +362,6 @@ GRUB_MOD_INIT(minicmd) cmd_exit = grub_register_command ("exit", grub_mini_cmd_exit, 0, N_("Exit from GRUB.")); - cmd_clear = - grub_register_command ("clear", grub_mini_cmd_clear, - 0, N_("Clear the screen.")); } GRUB_MOD_FINI(minicmd) @@ -387,5 +373,4 @@ GRUB_MOD_FINI(minicmd) grub_unregister_command (cmd_rmmod); grub_unregister_command (cmd_lsmod); grub_unregister_command (cmd_exit); - grub_unregister_command (cmd_clear); } diff --git a/include/grub/term.h b/include/grub/term.h index c744c3fb6..9fab96a69 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -263,8 +263,7 @@ void grub_putcode (grub_uint32_t code, struct grub_term_output *term); int EXPORT_FUNC(grub_getkey) (void); int EXPORT_FUNC(grub_checkkey) (void); int EXPORT_FUNC(grub_getkeystatus) (void); -void EXPORT_FUNC(grub_cls) (void); -void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); +void grub_cls (void); void EXPORT_FUNC(grub_refresh) (void); void grub_puts_terminal (const char *str, struct grub_term_output *term); grub_uint16_t *grub_term_save_pos (void); @@ -345,6 +344,15 @@ grub_term_setcolorstate (struct grub_term_output *term, term->setcolorstate (term, state); } +static inline void +grub_setcolorstate (grub_term_color_state state) +{ + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_term_setcolorstate (term, state); +} + /* Set the normal color and the highlight color. The format of each color is VGA's. */ static inline void diff --git a/kern/term.c b/kern/term.c index a1f8b9f93..47bd426fd 100644 --- a/kern/term.c +++ b/kern/term.c @@ -126,32 +126,6 @@ grub_getkeystatus (void) return status; } -void -grub_cls (void) -{ - struct grub_term_output *term; - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) - { - grub_putcode_dumb ('\n', term); - grub_term_refresh (term); - } - else - (term->cls) (term); - } -} - -void -grub_setcolorstate (grub_term_color_state state) -{ - struct grub_term_output *term; - - FOR_ACTIVE_TERM_OUTPUTS(term) - grub_term_setcolorstate (term, state); -} - void grub_refresh (void) { diff --git a/normal/main.c b/normal/main.c index 7d2459e62..e6b0f729a 100644 --- a/normal/main.c +++ b/normal/main.c @@ -692,6 +692,18 @@ grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)), return grub_strdup (val); } +/* clear */ +static grub_err_t +grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + grub_cls (); + return 0; +} + +static grub_command_t cmd_clear; + static void (*grub_xputs_saved) (const char *str); GRUB_MOD_INIT(normal) @@ -705,6 +717,10 @@ GRUB_MOD_INIT(normal) if (mod) grub_dl_ref (mod); + cmd_clear = + grub_register_command ("clear", grub_mini_cmd_clear, + 0, N_("Clear the screen.")); + grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); grub_register_variable_hook ("pager", 0, grub_env_write_pager); @@ -734,4 +750,6 @@ GRUB_MOD_FINI(normal) grub_register_variable_hook ("pager", 0, 0); grub_fs_autoload_hook = 0; free_handler_list (); + + grub_unregister_command (cmd_clear); } diff --git a/normal/term.c b/normal/term.c index 47e61c5e8..46ca95843 100644 --- a/normal/term.c +++ b/normal/term.c @@ -774,3 +774,20 @@ grub_xputs_normal (const char *str) } grub_free (unicode_str); } + +void +grub_cls (void) +{ + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) + { + grub_putcode ('\n', term); + grub_term_refresh (term); + } + else + (term->cls) (term); + } +} From 942a10c71e5de8a106344b91deae991cd3e30a44 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 18:25:42 +0200 Subject: [PATCH 392/503] * font/font.c (grub_font_get_glyph_with_fallback): Avoid dereferencing NULL font. --- ChangeLog | 5 +++++ font/font.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index dcdb3a7ae..f26c62431 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-02 Vladimir Serbinenko + + * font/font.c (grub_font_get_glyph_with_fallback): Avoid dereferencing + NULL font. + 2010-07-02 Colin Watson * util/deviceiter.c (grub_util_iterate_devices): Skip device-mapper diff --git a/font/font.c b/font/font.c index 9a89cadc5..89e993146 100644 --- a/font/font.c +++ b/font/font.c @@ -1029,6 +1029,8 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) next = node->next; glyph = grub_font_get_glyph_internal (curfont, code); + if (glyph && !font) + return glyph; if (glyph) { int d; From 4037210375271ec4eb80e942a518e5f9de5a58f0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 18:28:54 +0200 Subject: [PATCH 393/503] * gfxmenu/gui_list.c (draw_menu): Use viewport to simplify code and fix too long captions. (list_get_minimal_size): Take selection box into account. --- ChangeLog | 6 ++++++ gfxmenu/gui_list.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index f26c62431..36dd9fb49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Vladimir Serbinenko + + * gfxmenu/gui_list.c (draw_menu): Use viewport to simplify code and fix + too long captions. + (list_get_minimal_size): Take selection box into account. + 2010-07-02 Vladimir Serbinenko * font/font.c (grub_font_get_glyph_with_fallback): Avoid dereferencing diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index 8583a214e..8058fcc4f 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -210,7 +210,7 @@ draw_scrollbar (list_impl_t self, /* Draw the list of items. */ static void -draw_menu (list_impl_t self, int width, int num_shown_items) +draw_menu (list_impl_t self, int num_shown_items) { if (! self->menu_box || ! self->selected_item_box) return; @@ -227,10 +227,18 @@ draw_menu (list_impl_t self, int width, int num_shown_items) grub_gfxmenu_box_t selbox = self->selected_item_box; int sel_leftpad = selbox->get_left_pad (selbox); - int item_top = boxpad; - int item_left = boxpad + sel_leftpad; + int sel_toppad = selbox->get_top_pad (selbox); + int item_top = sel_toppad; int menu_index; int visible_index; + struct grub_video_rect oviewport; + + grub_video_get_viewport (&oviewport.x, &oviewport.y, + &oviewport.width, &oviewport.height); + grub_video_set_viewport (oviewport.x + boxpad, + oviewport.y + boxpad, + oviewport.width - 2 * boxpad, + oviewport.height - 2 * boxpad); for (visible_index = 0, menu_index = self->first_shown_index; visible_index < num_shown_items && menu_index < self->view->menu->size; @@ -240,16 +248,16 @@ draw_menu (list_impl_t self, int width, int num_shown_items) if (is_selected) { - int sel_toppad = selbox->get_top_pad (selbox); - selbox->set_content_size (selbox, (width - 2 * boxpad), item_height); - selbox->draw (selbox, item_left - sel_leftpad, + selbox->set_content_size (selbox, oviewport.width - 2 * boxpad - 2, + item_height - 1); + selbox->draw (selbox, 0, item_top - sel_toppad); } struct grub_video_bitmap *icon; if ((icon = get_item_icon (self, menu_index)) != 0) grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, - item_left, + sel_leftpad, item_top + (item_height - self->icon_height) / 2, 0, 0, self->icon_width, self->icon_height); @@ -266,12 +274,16 @@ draw_menu (list_impl_t self, int width, int num_shown_items) grub_font_draw_string (item_title, font, grub_gui_map_color (text_color), - item_left + self->icon_width + icon_text_space, + sel_leftpad + self->icon_width + icon_text_space, (item_top + (item_height - (ascent + descent)) / 2 + ascent)); item_top += item_height + item_vspace; } + grub_video_set_viewport (oviewport.x, + oviewport.y, + oviewport.width, + oviewport.height); } static void @@ -313,7 +325,7 @@ list_paint (void *vself, const grub_video_rect_t *region) box->draw (box, 0, 0); grub_gui_set_viewport (&content_rect, &vpsave2); - draw_menu (self, content_rect.width, num_shown_items); + draw_menu (self, num_shown_items); grub_gui_restore_viewport (&vpsave2); if (drawing_scrollbar) @@ -322,7 +334,7 @@ list_paint (void *vself, const grub_video_rect_t *region) 0, self->view->menu->size, self->bounds.width - box_right_pad + self->scrollbar_width, - box_top_pad + self->item_padding, + box_top_pad, self->bounds.height - box_top_pad - box_bottom_pad); } @@ -375,6 +387,9 @@ list_get_minimal_size (void *vself, unsigned *width, unsigned *height) int box_right_pad = box->get_right_pad (box); int box_bottom_pad = box->get_bottom_pad (box); unsigned width_s; + + grub_gfxmenu_box_t selbox = self->selected_item_box; + int sel_toppad = selbox->get_top_pad (selbox); *width = grub_font_get_string_width (self->item_font, "Typical OS"); width_s = grub_font_get_string_width (self->selected_item_font, @@ -388,7 +403,7 @@ list_get_minimal_size (void *vself, unsigned *width, unsigned *height) *height = (item_height * num_items + item_vspace * (num_items - 1) + 2 * boxpad - + box_top_pad + box_bottom_pad); + + box_top_pad + box_bottom_pad + sel_toppad); } else { From 50f0bcdab58ff554916fb0dda7bb4505f0ac1484 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 2 Jul 2010 18:04:54 +0100 Subject: [PATCH 394/503] * include/grub/types.h: Define the C99-style PRIxGRUB_SIZE macro, suitable for using within the format argument of printf when converting grub_size_t. * disk/usbms.c (grub_usbms_transfer): Use PRIxGRUB_SIZE rather than "x" to convert grub_size_t arguments. --- ChangeLog | 8 ++++++++ disk/usbms.c | 4 ++-- include/grub/types.h | 8 ++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 36dd9fb49..47da0d981 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-07-02 Colin Watson + + * include/grub/types.h: Define the C99-style PRIxGRUB_SIZE macro, + suitable for using within the format argument of printf when + converting grub_size_t. + * disk/usbms.c (grub_usbms_transfer): Use PRIxGRUB_SIZE rather than + "x" to convert grub_size_t arguments. + 2010-07-02 Vladimir Serbinenko * gfxmenu/gui_list.c (draw_menu): Use viewport to simplify code and fix diff --git a/disk/usbms.c b/disk/usbms.c index a49b30e7e..f913ee3f7 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -312,7 +312,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, grub_dprintf ("usb", "buf:\n"); if (size <= 64) for (i=0; i Date: Fri, 2 Jul 2010 20:37:08 +0200 Subject: [PATCH 395/503] Skip bidi if no RTL characters are present --- normal/charset.c | 290 +++++++++++++++++++++++++---------------------- 1 file changed, 152 insertions(+), 138 deletions(-) diff --git a/normal/charset.c b/normal/charset.c index 0fcc2a440..fd377e1c6 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -859,6 +859,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, unsigned run_start, run_end; struct grub_unicode_glyph *visual; unsigned cur_level; + int bidi_needed = 0; auto void push_stack (unsigned new_override, unsigned new_level); void push_stack (unsigned new_override, unsigned new_level) @@ -967,9 +968,11 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, switch (type) { case GRUB_BIDI_TYPE_RLE: + bidi_needed = 1; push_stack (cur_override, (cur_level | 1) + 1); break; case GRUB_BIDI_TYPE_RLO: + bidi_needed = 1; push_stack (OVERRIDE_R, (cur_level | 1) + 1); break; case GRUB_BIDI_TYPE_LRE: @@ -983,6 +986,9 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, break; case GRUB_BIDI_TYPE_BN: break; + case GRUB_BIDI_TYPE_R: + case GRUB_BIDI_TYPE_AL: + bidi_needed = 1; default: { if (join_state == JOIN_FORCE) @@ -1017,166 +1023,174 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, } } - for (run_start = 0; run_start < visual_len; run_start = run_end) + if (bidi_needed) { - unsigned prev_level, next_level, cur_run_level; - unsigned last_type, last_strong_type; - for (run_end = run_start; run_end < visual_len && - levels[run_end] == levels[run_start]; run_end++); - if (run_start == 0) - prev_level = base_level; - else - prev_level = levels[run_start - 1]; - if (run_end == visual_len) - next_level = base_level; - else - next_level = levels[run_end]; - cur_run_level = levels[run_start]; - if (prev_level & 1) - last_type = GRUB_BIDI_TYPE_R; - else - last_type = GRUB_BIDI_TYPE_L; - last_strong_type = last_type; - for (i = run_start; i < run_end; i++) + for (run_start = 0; run_start < visual_len; run_start = run_end) { - switch (resolved_types[i]) + unsigned prev_level, next_level, cur_run_level; + unsigned last_type, last_strong_type; + for (run_end = run_start; run_end < visual_len && + levels[run_end] == levels[run_start]; run_end++); + if (run_start == 0) + prev_level = base_level; + else + prev_level = levels[run_start - 1]; + if (run_end == visual_len) + next_level = base_level; + else + next_level = levels[run_end]; + cur_run_level = levels[run_start]; + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + last_strong_type = last_type; + for (i = run_start; i < run_end; i++) { - case GRUB_BIDI_TYPE_NSM: - resolved_types[i] = last_type; - break; - case GRUB_BIDI_TYPE_EN: - if (last_strong_type == GRUB_BIDI_TYPE_AL) - resolved_types[i] = GRUB_BIDI_TYPE_AN; - break; - case GRUB_BIDI_TYPE_L: - case GRUB_BIDI_TYPE_R: - last_strong_type = resolved_types[i]; - break; - case GRUB_BIDI_TYPE_ES: - if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end - && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) - resolved_types[i] = GRUB_BIDI_TYPE_EN; - else - resolved_types[i] = GRUB_BIDI_TYPE_ON; - break; - case GRUB_BIDI_TYPE_ET: - { - unsigned j; - if (last_type == GRUB_BIDI_TYPE_EN) - { + switch (resolved_types[i]) + { + case GRUB_BIDI_TYPE_NSM: + resolved_types[i] = last_type; + break; + case GRUB_BIDI_TYPE_EN: + if (last_strong_type == GRUB_BIDI_TYPE_AL) + resolved_types[i] = GRUB_BIDI_TYPE_AN; + break; + case GRUB_BIDI_TYPE_L: + case GRUB_BIDI_TYPE_R: + last_strong_type = resolved_types[i]; + break; + case GRUB_BIDI_TYPE_ES: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) resolved_types[i] = GRUB_BIDI_TYPE_EN; - break; - } - for (j = i; j < run_end - && resolved_types[j] == GRUB_BIDI_TYPE_ET; j++); - if (j != run_end && resolved_types[j] == GRUB_BIDI_TYPE_EN) + else + resolved_types[i] = GRUB_BIDI_TYPE_ON; + break; + case GRUB_BIDI_TYPE_ET: { + unsigned j; + if (last_type == GRUB_BIDI_TYPE_EN) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + for (j = i; j < run_end + && resolved_types[j] == GRUB_BIDI_TYPE_ET; j++); + if (j != run_end && resolved_types[j] == GRUB_BIDI_TYPE_EN) + { + for (; i < run_end + && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) + resolved_types[i] = GRUB_BIDI_TYPE_EN; + i--; + break; + } for (; i < run_end && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) - resolved_types[i] = GRUB_BIDI_TYPE_EN; + resolved_types[i] = GRUB_BIDI_TYPE_ON; i--; - break; + break; } - for (; i < run_end - && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) + break; + case GRUB_BIDI_TYPE_CS: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } + if (last_type == GRUB_BIDI_TYPE_AN + && i + 1 < run_end + && (resolved_types[i + 1] == GRUB_BIDI_TYPE_AN + || (resolved_types[i + 1] == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_AL))) + { + resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + } resolved_types[i] = GRUB_BIDI_TYPE_ON; - i--; - break; - } - break; - case GRUB_BIDI_TYPE_CS: - if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end - && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) - { - resolved_types[i] = GRUB_BIDI_TYPE_EN; + break; + case GRUB_BIDI_TYPE_AL: + last_strong_type = resolved_types[i]; + resolved_types[i] = GRUB_BIDI_TYPE_R; + break; + default: /* Make GCC happy. */ break; } - if (last_type == GRUB_BIDI_TYPE_AN - && i + 1 < run_end - && (resolved_types[i + 1] == GRUB_BIDI_TYPE_AN - || (resolved_types[i + 1] == GRUB_BIDI_TYPE_EN - && last_strong_type == GRUB_BIDI_TYPE_AL))) - { - resolved_types[i] = GRUB_BIDI_TYPE_EN; - break; - } - resolved_types[i] = GRUB_BIDI_TYPE_ON; - break; - case GRUB_BIDI_TYPE_AL: - last_strong_type = resolved_types[i]; - resolved_types[i] = GRUB_BIDI_TYPE_R; - break; - default: /* Make GCC happy. */ - break; + last_type = resolved_types[i]; + if (resolved_types[i] == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_L) + resolved_types[i] = GRUB_BIDI_TYPE_L; } - last_type = resolved_types[i]; - if (resolved_types[i] == GRUB_BIDI_TYPE_EN - && last_strong_type == GRUB_BIDI_TYPE_L) - resolved_types[i] = GRUB_BIDI_TYPE_L; - } - if (prev_level & 1) - last_type = GRUB_BIDI_TYPE_R; - else - last_type = GRUB_BIDI_TYPE_L; - for (i = run_start; i < run_end; ) - { - unsigned j; - unsigned next_type; - for (j = i; j < run_end && - (resolved_types[j] == GRUB_BIDI_TYPE_B - || resolved_types[j] == GRUB_BIDI_TYPE_S - || resolved_types[j] == GRUB_BIDI_TYPE_WS - || resolved_types[j] == GRUB_BIDI_TYPE_ON); j++); - if (j == i) + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + for (i = run_start; i < run_end; ) { - if (resolved_types[i] == GRUB_BIDI_TYPE_L) - last_type = GRUB_BIDI_TYPE_L; + unsigned j; + unsigned next_type; + for (j = i; j < run_end && + (resolved_types[j] == GRUB_BIDI_TYPE_B + || resolved_types[j] == GRUB_BIDI_TYPE_S + || resolved_types[j] == GRUB_BIDI_TYPE_WS + || resolved_types[j] == GRUB_BIDI_TYPE_ON); j++); + if (j == i) + { + if (resolved_types[i] == GRUB_BIDI_TYPE_L) + last_type = GRUB_BIDI_TYPE_L; + else + last_type = GRUB_BIDI_TYPE_R; + i++; + continue; + } + if (j == run_end) + next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; else - last_type = GRUB_BIDI_TYPE_R; - i++; + { + if (resolved_types[j] == GRUB_BIDI_TYPE_L) + next_type = GRUB_BIDI_TYPE_L; + else + next_type = GRUB_BIDI_TYPE_R; + } + if (next_type == last_type) + for (; i < j; i++) + resolved_types[i] = last_type; + else + for (; i < j; i++) + resolved_types[i] = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R + : GRUB_BIDI_TYPE_L; + } + } + + for (i = 0; i < visual_len; i++) + { + if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R) + { + levels[i]++; continue; } - if (j == run_end) - next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; - else + if (!(levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_AN + || resolved_types[i] == GRUB_BIDI_TYPE_EN)) { - if (resolved_types[j] == GRUB_BIDI_TYPE_L) - next_type = GRUB_BIDI_TYPE_L; - else - next_type = GRUB_BIDI_TYPE_R; + levels[i] += 2; + continue; + } + if ((levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_L + || resolved_types[i] == GRUB_BIDI_TYPE_AN + || resolved_types[i] == GRUB_BIDI_TYPE_EN)) + { + levels[i]++; + continue; } - if (next_type == last_type) - for (; i < j; i++) - resolved_types[i] = last_type; - else - for (; i < j; i++) - resolved_types[i] = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R - : GRUB_BIDI_TYPE_L; } } - - for (i = 0; i < visual_len; i++) + else { - if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R) - { - levels[i]++; - continue; - } - if (!(levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_AN - || resolved_types[i] == GRUB_BIDI_TYPE_EN)) - { - levels[i] += 2; - continue; - } - if ((levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_L - || resolved_types[i] == GRUB_BIDI_TYPE_AN - || resolved_types[i] == GRUB_BIDI_TYPE_EN)) - { - levels[i]++; - continue; - } + for (i = 0; i < visual_len; i++) + levels[i] = 0; } grub_free (resolved_types); From 169ed0dc6948aa75b50ec404615758bbb4c563f5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 22:05:47 +0200 Subject: [PATCH 396/503] Add missing include --- kern/ieee1275/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index 51668986a..99ce7179b 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include From 41ca7b81a96d09e7a11c609c46e8b117fedd0995 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 22:06:19 +0200 Subject: [PATCH 397/503] Fix letters reversing in qemu --- kern/i386/qemu/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/i386/qemu/init.c b/kern/i386/qemu/init.c index ff4c7b62f..201ba3633 100644 --- a/kern/i386/qemu/init.c +++ b/kern/i386/qemu/init.c @@ -61,7 +61,7 @@ load_font (void) grub_vga_gr_write (0xff, GRUB_VGA_GR_BITMASK); for (i = 0; i < 128; i++) - grub_memcpy ((void *) (0xa0000 + 32 * i), ascii_bitmaps + 16 * (0x7f - i), 16); + grub_memcpy ((void *) (0xa0000 + 32 * i), ascii_bitmaps + 16 * i, 16); } static void From fb73efb7944841f98053a0b76a6108e0ab541080 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 22:06:43 +0200 Subject: [PATCH 398/503] Fix mismerge --- commands/help.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/commands/help.c b/commands/help.c index 964f8f5ac..7ccfc4fac 100644 --- a/commands/help.c +++ b/commands/help.c @@ -49,19 +49,20 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); if (!command_help) - return 1; + break; grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, &unicode_last_position); + FOR_ACTIVE_TERM_OUTPUTS(term) { unsigned stringwidth; grub_uint32_t *unicode_last_screen_position; - + unicode_last_screen_position = unicode_command_help; - + stringwidth = 0; - + while (unicode_last_screen_position < unicode_last_position && stringwidth < ((grub_term_width (term) / 2) - 2)) { From c23bb3837f05aca785d9885cdc6e5a96113924fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Jul 2010 22:07:56 +0200 Subject: [PATCH 399/503] Update ChangeLog --- ChangeLog.bidi | 119 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 13 deletions(-) diff --git a/ChangeLog.bidi b/ChangeLog.bidi index 972e6e356..64539f5e9 100644 --- a/ChangeLog.bidi +++ b/ChangeLog.bidi @@ -7,7 +7,6 @@ (TARGET_CFLAGS): Add -DHAVE_UNIFONT_WIDTHSPEC=1 if font was available. * autogen.sh: Generate unidata.c. * commands/cat.c (grub_cmd_cat): Don't use grub_putchar. - * commands/handler.c (grub_cmd_handler): Likewise. * commands/ls.c (grub_ls_list_devices): Likewise. (grub_ls_list_files): Likewise. * commands/minicmd.c (grub_mini_cmd_cat): Likewise. @@ -28,6 +27,12 @@ (charset_mod_SOURCES): Removed. (charset_mod_CFLAGS): Likewise. (charset_mod_LDFLAGS): Likewise. + (pkglib_MODULES) [ieee1275]: Remove terminfo.mod. + * conf/powerpc-ieee1275.rmk (kernel_img_SOURCES): Add term/terminfo.c + and term/tparm.c. + * conf/sparc64-ieee1275.rmk (kernel_img_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (kernel_img_SOURCES): Likewise. + (kernel_img_HEADERS): Add terminfo.h. * font/font.c (ascii_glyph_lookup): Return NULL on failure. Fill ->font. Reverse ascii bitmaps. (grub_font_get_xheight): New function. @@ -67,23 +72,45 @@ (grub_normal_get_char_counter): New proto. (grub_normal_reset_more): Likewise. (grub_xputs_normal): Likewise. + * include/grub/powerpc/ieee1275/console.h: Removed. + * include/grub/sparc64/ieee1275/console.h: Likewise. * include/grub/term.h (GRUB_TERM_CODE_TYPE_MASK): New definition. (GRUB_TERM_CODE_TYPE_ASCII): Likewise. - (GRUB_TERM_CODE_TYPE_VGA): Likewise. + (GRUB_TERM_CODE_TYPE_CP437): Likewise. (GRUB_TERM_CODE_TYPE_UTF8_LOGICAL): Likewise. (GRUB_TERM_CODE_TYPE_UTF8_VISUAL): Likewise. (GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS): Likewise. + (grub_term_input): Pass reference to self. All users updated. (grub_term_output): Pass grub_unicode_glyph to putchar and getcharwidth. - All users updated. + Pass reference to self. New fields normal_color, highlight_color and + data. All users updated. (grub_putchar): Removed. (grub_putcode): Remove EXPORT_FUNC since it's not in kernel anymore. (grub_unicode_estimate_width): New function. (grub_term_getcharwidth): Add defaults. + (GRUB_TERM_DEFAULT_NORMAL_COLOR): New definition. + (GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR): Likewise. + (GRUB_TERM_DEFAULT_STANDARD_COLOR): Likewise. + (grub_cls): Remove EXPORT_FUNC. + (grub_setcolorstate): Inline. + (grub_newline_hook): Removed. + * include/grub/terminfo.h: Rewritten. All users updated. * include/grub/unicode.h: New file. * include/grub/video.h (grub_video_signed_rect): New type. + * kern/emu/console.c (grub_console_highlight_color): Removed. + (grub_console_normal_color): Likewise. + (grub_console_standard_color): Made static. + (grub_ncurses_putchar): Remove mapping. + (grub_ncurses_getcharwidth): Removed. + (grub_ncurses_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII. + (grub_ncurses_setcolor): Removed. + (grub_ncurses_getcolor): Likewise. * kern/i386/pc/startup.S (grub_console_real_putchar): Renamed to ... (grub_console_putchar): ... this. (grub_console_putchar): Handle argument difference. + * kern/ieee1275/init.c (grub_machine_init): Split console_init into + console_init_early and console_init_lately. + * kern/sparc64/ieee1275/init.c (grub_machine_init): Likewise. * kern/misc.c (grub_puts): Removed. (grub_vprintf): Store UTF-8 string instead of outputting it directly. (grub_vsnprintf_real): Remove str = NULL support. @@ -94,7 +121,6 @@ (grub_putchar): Removed. (grub_xputs_dumb): New function. (grub_xputs): New variable. - (grub_cls): Use grub_putcode_dumb. * lib/charset.c: Move from here ... * normal/charset.c: ... to here. (grub_ucs4_to_utf8): New function. @@ -174,25 +200,89 @@ * term/i386/vga_common.c (map_char): Removed. (grub_console_putchar): Likewise. (grub_console_getcharwidth): Likewise. - * term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Remove mapping. + * term/ieee1275/ofconsole.c: Simplify using terminfo. + (colors): Reordered to match terminfo. + (grub_ofconsole_normal_color): Removed. + (grub_ofconsole_writeesc): Likewise. + (grub_ofconsole_highlight_color): Likewise. + (grub_ofconsole_getcharwidth): Likewise. + (grub_ofconsole_setcolorstate): Likewise. + (grub_ofconsole_setcolor): Likewise. + (grub_ofconsole_getcolor): Likewise. + (grub_ofconsole_readkey): Renamed to ... + (readkey): ... this. Remove escape sequence handling. Return -1 on no + key. + (grub_ofconsole_checkkey): Removed. + (grub_ofconsole_getkey): Likewise. + (grub_ofconsole_getxy): Likewise. + (grub_ofconsole_gotoxy): Likewise. + (grub_ofconsole_cls): Likewise. + (grub_ofconsole_refresh): Likewise. + (grub_ofconsole_terminfo_input): New struct. + (grub_ofconsole_terminfo_output): Likewise. + (grub_ofconsole_term_input): Use terminfo. + (grub_ofconsole_term_output): Likewise. + (grub_console_init): Split into ... + (grub_console_init_early): ...this and ... + (grub_console_init_lately): ...this. Use terminfo. + (grub_ofconsole_putchar): Renamed to ... + (put): ... this. Remove mapping. (grub_ofconsole_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII. - * term/serial.c (options): New options ascii, utf8 and visual-utf8. - (grub_serial_putchar): Remove mapping. Use estimated_width. - (grub_cmd_serial): Handle charset arguments. - * term/terminfo.c (putstr): Use putchar directly. + * term/serial.c: Simplify using terminfo. + (xpos): Removed. + (ypos): Likewise. + (keep_track): Likewise. + (registered): Likewise. + (input_buf): Likewise. + (npending): Likewise. + (serial_translate_key_sequence): Likewise. + (fill_input_buf): Likewise. + (grub_serial_checkkey): Likewise. + (grub_serial_getkey): Likewise. + (grub_serial_getxy): Likewise. + (grub_serial_gotoxy): Likewise. + (grub_serial_putchar): Likewise. + (grub_serial_cls): Likewise. + (grub_serial_setcolorstate): Likewise. + (grub_serial_setcursor): Likewise. + (serial_hw_init): Use serial_hw_fetch. + (grub_serial_terminfo_input): New variable. + (grub_serial_terminfo_output): Likewise. + (grub_serial_term_input): Use terminfo. + (grub_serial_term_output): Likewise. + * term/terminfo.c (putstr): Use put. + (grub_terminfo_all_free): New function + (grub_terminfo_set_current): New types vt100-color, ieee1275 and dumb. + (grub_terminfo_output_register): New function. + (grub_terminfo_output_unregister): Likewise. + (grub_terminfo_getxy): Likewise. + (grub_terminfo_readkey): Likewise. + (grub_terminfo_checkkey): Likewise. + (grub_terminfo_getkey): Likewise. + (grub_terminfo_input_init): Likewise. + (print_terminfo): Likewise. + (grub_cmd_terminfo): Handle encoding. + (grub_terminfo_gotoxy): Track position. + (grub_terminfo_cls): Likewise. + (grub_terminfo_putchar): Likewise. + (grub_terminfo_setcolorstate): Handle colors + (grub_terminfo_cursor_on): This ... + (grub_terminfo_cursor_off): ... and this merged into ... + (grub_terminfo_setcursor): ... this. + * term/tparm.c (grub_terminfo_tparm): Avoid NULL dereferencing. * unicode/ArabicShaping.txt: New file (imported from Unicode). * unicode/BidiMirroring.txt: Likewise. * unicode/UnicodeData.txt: Likewise. * unicode/COPYING: Likewise. - * util/console.c (grub_ncurses_putchar): Remove mapping. - (grub_ncurses_getcharwidth): Removed. - (grub_ncurses_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII. * util/grub-editenv.c (grub_putchar): Removed. (grub_xputs_real): New function. (grub_xputs): New variable. * util/grub-fstest.c (grub_putchar): Removed. (grub_xputs_real): New function. (grub_xputs): New variable. + * util/grub-mkdevicemap.c (grub_putchar): Removed. + (grub_xputs_real): New function. + (grub_xputs): New variable. * util/grub-probe.c (grub_putchar): Removed. (grub_xputs_real): New function. (grub_xputs): New variable. @@ -220,4 +310,7 @@ (add_font): Handle GSUB. (write_font_width_spec): New function. (main): Sort glyphs. - + * commands/minicmd.c (grub_mini_cmd_clear): Moved from here ... + * normal/main.c (grub_mini_cmd_clear): ..here. All users updated. + * kern/term.c (grub_cls): Moved from here... + * normal/term.c (grub_cls): ... here. From 6b654bb0a564e380d5bd2859bdf665c4002d8785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sun, 4 Jul 2010 11:13:31 +0200 Subject: [PATCH 400/503] Do not embed when there are multiple (top-level) partmaps. --- ChangeLog | 5 +++++ util/i386/pc/grub-setup.c | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 090e04cef..136e42185 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-04 Grégoire Sutre + + * util/i386/pc/grub-setup.c (setup): Do not embed when there are + multiple (top-level) partmaps. + 2010-07-02 Vladimir Serbinenko Bidi and diacritics support. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 9407c5d47..3fe7d5622 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -95,6 +95,7 @@ setup (const char *dir, grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; const char *dest_partmap; + int multiple_partmaps; grub_uint8_t *boot_drive; grub_disk_addr_t *kernel_sector; grub_uint16_t *boot_drive_check; @@ -356,10 +357,17 @@ setup (const char *dir, { if (p->parent) return 0; - dest_partmap = p->partmap->name; - return 1; + if (dest_partmap == NULL) + dest_partmap = p->partmap->name; + else if (strcmp (dest_partmap, p->partmap->name) != 0) + { + multiple_partmaps = 1; + return 1; + } + return 0; } dest_partmap = 0; + multiple_partmaps = 0; grub_partition_iterate (dest_dev->disk, identify_partmap); if (! dest_partmap) @@ -367,6 +375,11 @@ setup (const char *dir, grub_util_warn (_("Attempting to install GRUB to a partitionless disk. This is a BAD idea.")); goto unable_to_embed; } + if (multiple_partmaps) + { + grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet.")); + goto unable_to_embed; + } if (strcmp (dest_partmap, "msdos") == 0) grub_partition_iterate (dest_dev->disk, find_usable_region_msdos); From 653d6e94b0a2f5853a7bbab2597d888cd35cc54b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 4 Jul 2010 14:23:55 +0200 Subject: [PATCH 401/503] * util/i386/efi/grub-install.in: Don't use empty grub_device. Reported by: Tito Keitel. --- util/i386/efi/grub-install.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index 7fc78b434..269317cd0 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -236,7 +236,7 @@ fi # this command is allowed to fail (--target=fs already grants us that the # filesystem will be accessible). partmap_module= -for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do +for x in `$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`; do partmap_module="$partmap_module part_$x"; done From 72a2026d335662f269eb7e25e54de32065f0fccb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 4 Jul 2010 14:29:01 +0200 Subject: [PATCH 402/503] missing ChangeLog commit. --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 136e42185..b7a478ec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ * util/i386/pc/grub-setup.c (setup): Do not embed when there are multiple (top-level) partmaps. +2010-07-02 Vladimir Serbinenko + + * util/i386/efi/grub-install.in: Don't use empty grub_device. + Reported by: Tito Keitel. + 2010-07-02 Vladimir Serbinenko Bidi and diacritics support. From cb7f64b229948b1790bbcc5378b0acc63ac5b0eb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 4 Jul 2010 22:00:45 +0100 Subject: [PATCH 403/503] * kern/emu/getroot.c [__GNU__]: Include for munmap. --- ChangeLog | 4 ++++ kern/emu/getroot.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index b7a478ec9..01469ca8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-04 Colin Watson + + * kern/emu/getroot.c [__GNU__]: Include for munmap. + 2010-07-04 Grégoire Sutre * util/i386/pc/grub-setup.c (setup): Do not embed when there are diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index fa74c384b..24b2cd486 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -33,6 +33,7 @@ #include #include #include +#include #endif #include From 57ebd41ef1ac51a21948e762ce95dc67e7522c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 5 Jul 2010 00:45:14 +0200 Subject: [PATCH 404/503] Avoid == in test command, it's not portable. --- ChangeLog | 5 +++++ configure.ac | 2 +- util/grub.d/30_os-prober.in | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 01469ca8f..31020644e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-04 Grégoire Sutre + + * configure.ac: Avoid == in test command, it's not portable. + * util/grub.d/30_os-prober.in: Likewise. + 2010-07-04 Colin Watson * kern/emu/getroot.c [__GNU__]: Include for munmap. diff --git a/configure.ac b/configure.ac index e5840118c..55c2625cb 100644 --- a/configure.ac +++ b/configure.ac @@ -190,7 +190,7 @@ for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do done done -if test "x$FONT_SOURCE" == x && ( test "x$platform" = xqemu || test "x$platform" = xyeeloong ); then +if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xyeeloong ); then AC_MSG_ERROR([qemu and yeeloong ports need unifont]) fi diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 601663dcc..ecd87bb1c 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -52,7 +52,7 @@ EOF set do_resume=1 fi fi - if [ \$do_resume == 0 ]; then + if [ \$do_resume = 0 ]; then xnu_uuid ${OSXUUID} uuid if [ -f /Extra/DSDT.aml ]; then acpi -e /Extra/DSDT.aml From 38d8f4f3f7510baf4b6eec55036dedc47022bec5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 5 Jul 2010 01:09:00 +0100 Subject: [PATCH 405/503] * util/i386/pc/grub-setup.c (setup): Rename prefix to install_prefix, in line with install_dos_part and install_bsd_part. Add new prefix variable, which is copied to install_prefix after comparing core.img in memory with the one read from disk in the no-embedding case, and use that rather than overwriting install_prefix immediately when installing to a partition. Fixes Debian bug #586621; based on patches by Matt Kraai and M. Vefa Bicakci. --- ChangeLog | 11 +++++++++++ util/i386/pc/grub-setup.c | 20 ++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31020644e..9162f2bdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-07-05 Colin Watson + + * util/i386/pc/grub-setup.c (setup): Rename prefix to + install_prefix, in line with install_dos_part and install_bsd_part. + Add new prefix variable, which is copied to install_prefix after + comparing core.img in memory with the one read from disk in the + no-embedding case, and use that rather than overwriting + install_prefix immediately when installing to a partition. + Fixes Debian bug #586621; based on patches by Matt Kraai and M. Vefa + Bicakci. + 2010-07-04 Grégoire Sutre * configure.ac: Avoid == in test command, it's not portable. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 3fe7d5622..8b2f52bb4 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -102,7 +102,8 @@ setup (const char *dir, struct grub_boot_blocklist *first_block, *block; grub_int32_t *install_dos_part, *install_bsd_part; grub_int32_t dos_part, bsd_part; - char *prefix; + char *install_prefix; + char *prefix = NULL; char *tmp_img; int i; grub_disk_addr_t first_sector; @@ -234,8 +235,8 @@ setup (const char *dir, + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART); install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); - prefix = (char *) (core_img + GRUB_DISK_SECTOR_SIZE + - GRUB_KERNEL_MACHINE_PREFIX); + install_prefix = (char *) (core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_MACHINE_PREFIX); /* Open the root device and the destination device. */ root_dev = grub_device_open (root); @@ -312,15 +313,13 @@ setup (const char *dir, bsd_part = -1; } - if (prefix[0] != '(') + if (install_prefix[0] != '(') { - char *root_part_name, *new_prefix; + char *root_part_name; root_part_name = grub_partition_get_name (root_dev->disk->partition); - new_prefix = xasprintf ("(,%s)%s", root_part_name, prefix); - strcpy (prefix, new_prefix); - free (new_prefix); + prefix = xasprintf ("(,%s)%s", root_part_name, install_prefix); free (root_part_name); } } @@ -411,6 +410,8 @@ setup (const char *dir, *install_dos_part = grub_cpu_to_le32 (dos_part); *install_bsd_part = grub_cpu_to_le32 (bsd_part); + if (prefix) + strcpy (install_prefix, prefix); /* The first blocklist contains the whole sectors. */ first_block->start = grub_cpu_to_le64 (embed_region.start + 1); @@ -571,6 +572,8 @@ unable_to_embed: *install_dos_part = grub_cpu_to_le32 (dos_part); *install_bsd_part = grub_cpu_to_le32 (bsd_part); + if (prefix) + strcpy (install_prefix, prefix); /* Write the first two sectors of the core image onto the disk. */ grub_util_info ("opening the core image `%s'", core_path); @@ -590,6 +593,7 @@ unable_to_embed: /* Sync is a Good Thing. */ sync (); + free (prefix); free (core_path); free (core_img); free (boot_img); From e3f90044e1fd4336a21496d5e022d1e77c037b42 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 5 Jul 2010 01:24:10 +0100 Subject: [PATCH 406/503] * Makefile.in (MAINTAINER_CLEANFILES): Add unicode/UnicodeData.txt, unicode/BidiMirroring.txt, unicode/ArabicShaping.txt, and unidata.c. --- ChangeLog | 5 +++++ Makefile.in | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9162f2bdd..294c002f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-05 Colin Watson + + * Makefile.in (MAINTAINER_CLEANFILES): Add unicode/UnicodeData.txt, + unicode/BidiMirroring.txt, unicode/ArabicShaping.txt, and unidata.c. + 2010-07-05 Colin Watson * util/i386/pc/grub-setup.c (setup): Rename prefix to diff --git a/Makefile.in b/Makefile.in index 873ccdb75..9fec32c69 100644 --- a/Makefile.in +++ b/Makefile.in @@ -164,7 +164,10 @@ DISTCLEANFILES = config.status config.cache config.log config.h \ MAINTAINER_CLEANFILES = $(srcdir)/configure $(srcdir)/aclocal.m4 \ $(MKFILES) $(srcdir)/config.guess \ $(srcdir)/config.sub $(srcdir)/install-sh $(srcdir)/missing \ - $(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in $(INFOS) + $(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in \ + $(srcdir)/unicode/UnicodeData.txt $(srcdir)/unicode/BidiMirroring.txt \ + $(srcdir)/unicode/ArabicShaping.txt $(srcdir)/unidata.c \ + $(INFOS) # The default target. all: all-local From fcda2a1f80e8be57922849929b66af94db413649 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 5 Jul 2010 01:45:25 +0100 Subject: [PATCH 407/503] fix typo in reporter name --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 294c002f6..94f90ce73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,7 +31,7 @@ 2010-07-02 Vladimir Serbinenko * util/i386/efi/grub-install.in: Don't use empty grub_device. - Reported by: Tito Keitel. + Reported by: Tino Keitel. 2010-07-02 Vladimir Serbinenko From 5cf691510fe69e8a55f97a192ceb6c2510e9a009 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 5 Jul 2010 09:29:02 +0100 Subject: [PATCH 408/503] * Makefile.in: Set LINGUAS to empty if ENABLE_NLS is undefined. --- ChangeLog | 4 ++++ Makefile.in | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 94f90ce73..e2bcc44f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-05 Colin Watson + + * Makefile.in: Set LINGUAS to empty if ENABLE_NLS is undefined. + 2010-07-05 Colin Watson * Makefile.in (MAINTAINER_CLEANFILES): Add unicode/UnicodeData.txt, diff --git a/Makefile.in b/Makefile.in index 9fec32c69..ec3b72296 100644 --- a/Makefile.in +++ b/Makefile.in @@ -53,9 +53,13 @@ XGETTEXT = @XGETTEXT@ MSGMERGE = @MSGMERGE@ MSGFMT = @MSGFMT@ +ifdef ENABLE_NLS LINGUAS = $(shell for i in $(srcdir)/po/*.po ; do \ if test -e $$i ; then echo $$i ; fi ; \ done | sed -e "s,.*/po/\(.*\)\.po$$,\1,") +else +LINGUAS = +endif PACKAGE = @PACKAGE@ PACKAGE_NAME = @PACKAGE_NAME@ From e75056f162880ca73bbc520ae054c1a8b9513edb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 5 Jul 2010 11:08:04 +0100 Subject: [PATCH 409/503] * docs/grub.texi (Features): Update list of supported file systems. (GNU/Linux): Update for GRUB 2. (Serial terminal): Remove mention of --disable-serial, which was a GRUB Legacy configure option. Update instructions to use `terminal_input' and `terminal_output' rather than `terminal'. (Vendor power-on keys): Copy-edit. Add cross-references to `Simple configuration' and `Installing GRUB using grub-install'. (Menu entry editor): Update for GRUB 2. (terminfo): Add vt100-color, ieee1275, and dumb terminal types. Document new -a, -u, and -v options. (initrd): New section. (initrd16): New section. (linux): New section. (linux16): New section. (search): The `var' argument to `--set' is optional. (GRUB only offers a rescue shell): Go into a little more detail on drive ordering. --- ChangeLog | 20 ++++++ docs/grub.texi | 176 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 154 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index e2bcc44f6..81dfc1c78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-07-05 Colin Watson + + * docs/grub.texi (Features): Update list of supported file systems. + (GNU/Linux): Update for GRUB 2. + (Serial terminal): Remove mention of --disable-serial, which was a + GRUB Legacy configure option. Update instructions to use + `terminal_input' and `terminal_output' rather than `terminal'. + (Vendor power-on keys): Copy-edit. Add cross-references to `Simple + configuration' and `Installing GRUB using grub-install'. + (Menu entry editor): Update for GRUB 2. + (terminfo): Add vt100-color, ieee1275, and dumb terminal types. + Document new -a, -u, and -v options. + (initrd): New section. + (initrd16): New section. + (linux): New section. + (linux16): New section. + (search): The `var' argument to `--set' is optional. + (GRUB only offers a rescue shell): Go into a little more detail on + drive ordering. + 2010-07-05 Colin Watson * Makefile.in: Set LINGUAS to empty if ENABLE_NLS is undefined. diff --git a/docs/grub.texi b/docs/grub.texi index cf73a2d38..5d412ecd4 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -332,10 +332,12 @@ 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. +blocklist notation. The currently supported filesystem types are @dfn{Amiga +Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS}, @dfn{cpio}, @dfn{Linux +ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{HFS}, @dfn{HFS+}, +@dfn{ISO9660}, @dfn{JFS}, @dfn{Minix fs}, @dfn{nilfs2}, @dfn{NTFS}, +@dfn{ReiserFS}, @dfn{Amiga Smart FileSystem (SFS)}, @dfn{tar}, @dfn{UDF}, +@dfn{BSD UFS/UFS2}, and @dfn{XFS}. @xref{Filesystem}, for more information. @item Support automatic decompression Can decompress files which were compressed by @command{gzip}. This @@ -842,11 +844,36 @@ Run the command @command{boot} (@pxref{boot}). It is relatively easy to boot GNU/Linux from GRUB, because it somewhat resembles to boot a Multiboot-compliant OS. -FIXME: this section is incomplete. - @enumerate @item -Set GRUB's root device to the same drive as GNU/Linux's. +Set GRUB's root device to the same drive as GNU/Linux's. The command +@code{search --file --set /vmlinuz} or similar may help you +(@pxref{search}). + +@item +Load the kernel using the command @command{linux} (@pxref{linux}): + +@example +grub> @kbd{linux /vmlinuz root=/dev/sda1} +@end example + +If you need to specify some kernel parameters, just append them to the +command. For example, to set @option{acpi} to @samp{off}, do this: + +@example +grub> @kbd{linux /vmlinuz root=/dev/sda1 acpi=off} +@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{linux}: + +@example +grub> @kbd{initrd /initrd} +@end example @item Finally, run the command @command{boot} (@pxref{boot}). @@ -1278,18 +1305,13 @@ 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: +simple. Here is an example: @example @group grub> @kbd{serial --unit=0 --speed=9600} -grub> @kbd{terminal serial} +grub> @kbd{terminal_input serial} +grub> @kbd{terminal_output serial} @end group @end example @@ -1317,14 +1339,16 @@ menu requires several fancy features of your terminal. @node Vendor power-on keys @chapter Using GRUB with vendor power-on keys -Some laptop vendor provide an additional power-on button which boots another OS. -GRUB supports such buttons with GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON, -GRUB_HIDDEN_TIMEOUT_BUTTON and GRUB_BUTTON_CMOS_ADDRESS variables in -default/grub. GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON and -GRUB_HIDDEN_TIMEOUT_BUTTON are used instead of corresponding variables without -_BUTTON suffix when powered using special button. -GRUB_BUTTON_CMOS_ADDRESS is vendor specific and partially model-specific. -Values known to GRUB team are: + +Some laptop vendors provide an additional power-on button which boots another +OS. GRUB supports such buttons with the @samp{GRUB_TIMEOUT_BUTTON}, +@samp{GRUB_DEFAULT_BUTTON}, @samp{GRUB_HIDDEN_TIMEOUT_BUTTON} and +@samp{GRUB_BUTTON_CMOS_ADDRESS} variables in default/grub (@pxref{Simple +configuration}). @samp{GRUB_TIMEOUT_BUTTON}, @samp{GRUB_DEFAULT_BUTTON} and +@samp{GRUB_HIDDEN_TIMEOUT_BUTTON} are used instead of the corresponding +variables without the @samp{_BUTTON} suffix when powered on using the special +button. @samp{GRUB_BUTTON_CMOS_ADDRESS} is vendor-specific and partially +model-specific. Values known to the GRUB team are: @table @key @item Dell XPS M1530 @@ -1333,7 +1357,8 @@ Values known to GRUB team are: 84:1 (unconfirmed) @end table -To take full advantage of this function install GRUB into MBR. +To take full advantage of this function, install GRUB into the MBR +(@pxref{Installing GRUB using grub-install}). @node Images @@ -1695,19 +1720,12 @@ 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). +Each line in the menu entry can be edited freely, and you can add new lines +by pressing @key{RET} at the end of a line. To boot the edited entry, press +@key{Ctrl-x}. -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. +Although GRUB unfortunately does not support @dfn{undo}, you can do almost +the same thing by just returning to the main menu using @key{ESC}. @node Commands @@ -1856,16 +1874,23 @@ names active. @node terminfo @subsection terminfo -@deffn Command terminfo [term] +@deffn Command terminfo [-a|-u|-v] [term] Define the capabilities of your terminal by giving the name of an entry in the terminfo database, which should correspond roughly to a @samp{TERM} environment variable in Unix. -At the moment, only @samp{vt100} is supported in GRUB 2. If you need other -terminal types, please contact us to discuss the best way to include support -for these in GRUB. +The currently available terminal types are @samp{vt100}, @samp{vt100-color}, +@samp{ieee1275}, and @samp{dumb}. If you need other terminal types, please +contact us to discuss the best way to include support for these in GRUB. -If no option is specified, the current terminal type is printed. +The @option{-a} (@option{--ascii}), @option{-u} (@option{--utf8}), and +@option{-v} (@option{--visual-utf8}) options control how non-ASCII text is +displayed. @option{-a} specifies an ASCII-only terminal; @option{-u} +specifies logically-ordered UTF-8; and @option{-v} specifies +visually-ordered UTF-8. + +If no option or terminal type is specified, the current terminal type is +printed. @end deffn @@ -1895,8 +1920,12 @@ you forget a command, you can run the command @command{help} * gptsync:: Fill an MBR based on GPT entries * halt:: Shut down your computer * help:: Show help messages +* initrd:: Load a Linux initrd +* initrd16:: Load a Linux initrd (16-bit mode) * insmod:: Insert a module * keystatus:: Check key modifier status +* linux:: Load a Linux kernel +* linux16:: Load a Linux kernel (16-bit mode) * ls:: List devices or files * parttool:: Modify partition table entries * password:: Set a clear-text password @@ -2203,6 +2232,30 @@ about each of the commands whose names begin with those @var{patterns}. @end deffn +@node initrd +@subsection initrd + +@deffn Command initrd file +Load an initial ramdisk for a Linux kernel image, and set the appropriate +parameters in the Linux setup area in memory. This may only be used after +the @command{linux} command (@pxref{linux}) has been run. See also +@ref{GNU/Linux}. +@end deffn + + +@node initrd16 +@subsection initrd16 + +@deffn Command initrd16 file +Load an initial ramdisk for a Linux kernel image to be booted in 16-bit +mode, and set the appropriate parameters in the Linux setup area in memory. +This may only be used after the @command{linux16} command (@pxref{linux16}) +has been run. See also @ref{GNU/Linux}. + +This command is only available on x86 systems. +@end deffn + + @node insmod @subsection insmod @@ -2225,6 +2278,42 @@ only if checking key modifier status is supported. @end deffn +@node linux +@subsection linux + +@deffn Command linux file @dots{} +Load a Linux kernel image from @var{file}. The rest of the line is passed +verbatim as the @dfn{kernel command-line}. Any initrd must be reloaded +after using this command (@pxref{initrd}). + +On x86 systems, the kernel will be booted using the 32-bit boot protocol. +Note that this means that the @samp{vga=} boot option will not work; if you +want to set a special video mode, you will need to use GRUB commands such as +@samp{set gfxpayload=1024x768} or @samp{set gfxpayload=keep} (to keep the +same mode as used in GRUB) instead. GRUB can automatically detect some uses +of @samp{vga=} and translate them to appropriate settings of +@samp{gfxpayload}. The @command{linux16} command (@pxref{linux16}) avoids +this restriction. +@end deffn + + +@node linux16 +@subsection linux16 + +@deffn Command linux16 file @dots{} +Load a Linux kernel image from @var{file} in 16-bit mode. The rest of the +line is passed verbatim as the @dfn{kernel command-line}. Any initrd must +be reloaded after using this command (@pxref{initrd16}). + +The kernel will be booted using the traditional 16-bit boot protocol. As +well as bypassing problems with @samp{vga=} described in @ref{linux}, this +permits booting some other programs that implement the Linux boot protocol +for the sake of convenience. + +This command is only available on x86 systems. +@end deffn + + @node ls @subsection ls @@ -2337,7 +2426,7 @@ Reboot the computer. @deffn Command search @ [@option{--file}|@option{--label}|@option{--fs-uuid}] @ - [@option{--set} var] [@option{--no-floppy}] name + [@option{--set} [var]] [@option{--no-floppy}] name Search devices by file (@option{-f}, @option{--file}), filesystem label (@option{-l}, @option{--label}), or filesystem UUID (@option{-u}, @option{--fs-uuid}). @@ -2493,6 +2582,9 @@ grub-install}). When doing this, there are a few things to remember: Drive ordering in your operating system may not be the same as the boot drive ordering used by your firmware. Do not assume that your first hard drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from. +@file{device.map} (@pxref{Device map}) can be used to override this, but it +is usually better to use UUIDs or file system labels and avoid depending on +drive ordering entirely. @item At least on BIOS systems, if you tell @command{grub-install} to install GRUB From 1a0742d4e2a5a1d041b422391cbf8df7772a1d3a Mon Sep 17 00:00:00 2001 From: starous Date: Mon, 5 Jul 2010 19:02:05 +0200 Subject: [PATCH 410/503] USB hub support --- bus/usb/usbhub.c | 88 ++++++++++++++++++++++++++++++++++------- include/grub/usbtrans.h | 12 +++--- 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 523abf93e..034ccbe8d 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -75,14 +75,47 @@ grub_usb_add_hub (grub_usb_device_t dev) struct grub_usb_usb_hubdesc hubdesc; grub_err_t err; int i; + grub_uint64_t timeout; + grub_usb_device_t next_dev; + + err = 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); + if (err) + return err; + grub_dprintf ("usb", "Hub descriptor:\n\t\t len:%d, typ:0x%02x, cnt:%d, char:0x%02x, pwg:%d, curr:%d\n", + hubdesc.length, hubdesc.type, hubdesc.portcnt, + hubdesc.characteristics, hubdesc.pwdgood, + hubdesc.current); - 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); + /* Activate the first configuration. Hubs should have only one conf. */ + grub_dprintf ("usb", "Hub set configuration\n"); + grub_usb_set_configuration (dev, 1); + /* Power on all Hub ports. */ + for (i = 1; i <= hubdesc.portcnt; i++) + { + grub_dprintf ("usb", "Power on - port %d\n", i); + /* Power on the port and wait for possible device connect */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_POWER, + i, 0, NULL); + /* Just ignore the device if some error happened */ + if (err) + continue; + } + /* Wait for port power-on */ + if (hubdesc.pwdgood >= 50) + grub_millisleep (hubdesc.pwdgood * 2); + else + grub_millisleep (100); + /* Iterate over the Hub ports. */ for (i = 1; i <= hubdesc.portcnt; i++) { @@ -92,14 +125,14 @@ grub_usb_add_hub (grub_usb_device_t dev) 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, + GRUB_USB_REQ_GET_STATUS, 0, i, sizeof (status), (char *) &status); - /* Just ignore the device if the Hub does not report the status. */ if (err) continue; - + grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status); + /* If connected, reset and enable the port. */ if (status & GRUB_USB_HUB_STATUS_CONNECTED) { @@ -116,21 +149,46 @@ grub_usb_add_hub (grub_usb_device_t dev) 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! */ + /* A device is actually connected to this port. + * Now do reset of port. */ + grub_dprintf ("usb", "Reset hub port - port %d\n", i); err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_TARGET_OTHER), - 0x3, 0x4, i, 0, 0); - + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_RESET, + i, 0, 0); /* If the Hub does not cooperate for this port, just skip the port. */ if (err) continue; + /* Wait for reset procedure done */ + timeout = grub_get_time_ms () + 1000; + do + { + /* 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_GET_STATUS, + 0, i, sizeof (status), (char *) &status); + } + while (!err && + !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) && + (grub_get_time_ms() < timeout) ); + if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) ) + continue; + /* Add the device and assign a device address to it. */ - grub_usb_hub_add_dev (&dev->controller, speed); + grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i); + next_dev = grub_usb_hub_add_dev (&dev->controller, speed); + if (! next_dev) + continue; + + /* If the device is a Hub, scan it for more devices. */ + if (next_dev->descdev.class == 0x09) + grub_usb_add_hub (next_dev); } } diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 40fc0dd5f..8f49c246f 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -87,15 +87,17 @@ typedef struct grub_usb_transfer *grub_usb_transfer_t; #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 0x00 #define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01 #define GRUB_USB_FEATURE_TEST_MODE 0x02 -#define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) -#define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) -#define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10) +#define GRUB_USB_HUB_FEATURE_PORT_RESET 0x04 +#define GRUB_USB_HUB_FEATURE_PORT_POWER 0x08 + +#define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) +#define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) +#define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10) +#define GRUB_USB_HUB_STATUS_C_PORT_RESET (1 << 20) struct grub_usb_packet_setup { From 525ba5f9d0e69b1e7d4f20627a1495ef1779206b Mon Sep 17 00:00:00 2001 From: starous Date: Mon, 5 Jul 2010 19:06:47 +0200 Subject: [PATCH 411/503] UHCI portstatus correction --- bus/usb/uhci.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 1510f98e8..e85f07a6f 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -612,8 +612,23 @@ grub_uhci_portstatus (grub_usb_controller_t dev, status = grub_uhci_readreg16 (u, reg); grub_dprintf ("uhci", "detect=0x%02x\n", status); + if (!enable) /* We don't need reset port */ + { + /* Disable the port. */ + grub_uhci_writereg16 (u, reg, 0 << 2); + grub_dprintf ("uhci", "waiting for the port to be disabled\n"); + endtime = grub_get_time_ms () + 1000; + while ((grub_uhci_readreg16 (u, reg) & (1 << 2))) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, "UHCI Timed out"); + + status = grub_uhci_readreg16 (u, reg); + grub_dprintf ("uhci", ">3detect=0x%02x\n", status); + return GRUB_ERR_NONE; + } + /* Reset the port. */ - grub_uhci_writereg16 (u, reg, enable << 9); + grub_uhci_writereg16 (u, reg, 1 << 9); /* Wait for the reset to complete. XXX: How long exactly? */ grub_millisleep (50); /* For root hub should be nominaly 50ms */ @@ -623,7 +638,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_millisleep (10); /* Enable the port. */ - grub_uhci_writereg16 (u, reg, enable << 2); + grub_uhci_writereg16 (u, reg, 1 << 2); grub_millisleep (10); grub_dprintf ("uhci", "waiting for the port to be enabled\n"); From f1f7d19ead04bb5fca0352c39fc1039970c2d4f9 Mon Sep 17 00:00:00 2001 From: starous Date: Mon, 5 Jul 2010 20:34:27 +0200 Subject: [PATCH 412/503] ChangeLog & usbhub.c correction --- ChangeLog | 4 ++++ bus/usb/usbhub.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 81dfc1c78..5b5717c18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-05 Ales Nesrsta + * bus/usb/usbhub.c, usbtrans.h: Simple USB hub support + * bus/usb/uhci.c: UHCI portstatus correction + 2010-07-05 Colin Watson * docs/grub.texi (Features): Update list of supported file systems. diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 034ccbe8d..2bbc850d0 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -21,6 +21,7 @@ #include #include #include +#include /* USB Supports 127 devices, with device 0 as special case. */ static struct grub_usb_device *grub_usb_devs[128]; From 75d959ea7c4d0a6768afb2fab7a6b934c8cd3960 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 6 Jul 2010 01:55:26 +0200 Subject: [PATCH 413/503] =?UTF-8?q?Revert=20latest=20two=20Ale=C5=A1'=20co?= =?UTF-8?q?mmits?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 4 ---- bus/usb/uhci.c | 19 ++----------------- bus/usb/usbhub.c | 1 - 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b5717c18..81dfc1c78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,3 @@ -2010-07-05 Ales Nesrsta - * bus/usb/usbhub.c, usbtrans.h: Simple USB hub support - * bus/usb/uhci.c: UHCI portstatus correction - 2010-07-05 Colin Watson * docs/grub.texi (Features): Update list of supported file systems. diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index e85f07a6f..1510f98e8 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -612,23 +612,8 @@ grub_uhci_portstatus (grub_usb_controller_t dev, status = grub_uhci_readreg16 (u, reg); grub_dprintf ("uhci", "detect=0x%02x\n", status); - if (!enable) /* We don't need reset port */ - { - /* Disable the port. */ - grub_uhci_writereg16 (u, reg, 0 << 2); - grub_dprintf ("uhci", "waiting for the port to be disabled\n"); - endtime = grub_get_time_ms () + 1000; - while ((grub_uhci_readreg16 (u, reg) & (1 << 2))) - if (grub_get_time_ms () > endtime) - return grub_error (GRUB_ERR_IO, "UHCI Timed out"); - - status = grub_uhci_readreg16 (u, reg); - grub_dprintf ("uhci", ">3detect=0x%02x\n", status); - return GRUB_ERR_NONE; - } - /* Reset the port. */ - grub_uhci_writereg16 (u, reg, 1 << 9); + grub_uhci_writereg16 (u, reg, enable << 9); /* Wait for the reset to complete. XXX: How long exactly? */ grub_millisleep (50); /* For root hub should be nominaly 50ms */ @@ -638,7 +623,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_millisleep (10); /* Enable the port. */ - grub_uhci_writereg16 (u, reg, 1 << 2); + grub_uhci_writereg16 (u, reg, enable << 2); grub_millisleep (10); grub_dprintf ("uhci", "waiting for the port to be enabled\n"); diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 2bbc850d0..034ccbe8d 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -21,7 +21,6 @@ #include #include #include -#include /* USB Supports 127 devices, with device 0 as special case. */ static struct grub_usb_device *grub_usb_devs[128]; From c8c069533f5c240855f292f7f77b3c784c5f7946 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 6 Jul 2010 09:42:37 +0100 Subject: [PATCH 414/503] * util/grub.d/00_header.in: Process GRUB_THEME and GRUB_BACKGROUND after setting gfxterm as the active terminal. GRUB_BACKGROUND doesn't work otherwise. --- ChangeLog | 6 +++ util/grub.d/00_header.in | 103 ++++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81dfc1c78..108379321 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-06 Colin Watson + + * util/grub.d/00_header.in: Process GRUB_THEME and GRUB_BACKGROUND + after setting gfxterm as the active terminal. GRUB_BACKGROUND + doesn't work otherwise. + 2010-07-05 Colin Watson * docs/grub.texi (Features): Update list of supported file systems. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 553369e37..75c8b0fa2 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -127,57 +127,6 @@ if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT_PATH}"` ; then set gfxmode=${GRUB_GFXMODE} load_video insmod gfxterm -EOF - if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \ - && is_path_readable_by_grub "$GRUB_THEME"; then - echo "Found theme: $GRUB_THEME" >&2 - prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"` | sed -e "s/^/ /" - cat << EOF - insmod gfxmenu -EOF - themedir="`dirname "$GRUB_THEME"`" - for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do - if [ -f "$x" ]; then - cat << EOF - loadfont (\$root)`make_system_path_relative_to_its_root $x` -EOF - fi - done - if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then - cat << EOF - insmod jpeg -EOF - fi - if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then - cat << EOF - insmod png -EOF - fi - if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then - cat << EOF - insmod tga -EOF - fi - - cat << EOF - set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` -EOF - elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \ - && is_path_readable_by_grub "$GRUB_BACKGROUND"; then - echo "Found background: $GRUB_BACKGROUND" >&2 - case "$GRUB_BACKGROUND" in - *.png) reader=png ;; - *.tga) reader=tga ;; - *.jpg|*.jpeg) reader=jpeg ;; - *) echo "Unsupported image format" >&2; exit 1 ;; - esac - prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"` | sed -e "s/^/ /" - cat << EOF - insmod $reader - background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"` -EOF - fi - cat << EOF fi EOF fi @@ -212,6 +161,58 @@ EOF ;; esac +if [ "x$gfxterm" = x1 ]; then + if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \ + && is_path_readable_by_grub "$GRUB_THEME"; then + echo "Found theme: $GRUB_THEME" >&2 + prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"` + cat << EOF +insmod gfxmenu +EOF + themedir="`dirname "$GRUB_THEME"`" + for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do + if [ -f "$x" ]; then + cat << EOF +loadfont (\$root)`make_system_path_relative_to_its_root $x` +EOF + fi + done + if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then + cat << EOF +insmod jpeg +EOF + fi + if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then + cat << EOF +insmod png +EOF + fi + if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then + cat << EOF +insmod tga +EOF + fi + + cat << EOF +set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` +EOF + elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \ + && is_path_readable_by_grub "$GRUB_BACKGROUND"; then + echo "Found background: $GRUB_BACKGROUND" >&2 + case "$GRUB_BACKGROUND" in + *.png) reader=png ;; + *.tga) reader=tga ;; + *.jpg|*.jpeg) reader=jpeg ;; + *) echo "Unsupported image format" >&2; exit 1 ;; + esac + prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"` + cat << EOF +insmod $reader +background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"` +EOF + fi +fi + # Gettext variables and module if [ "x${LANG}" != "xC" ] && [ -d "${locale_dir}" ] ; then prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) From 37582066cd74c544ecf9bbbc94c1d3b0ccdf4a7a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 6 Jul 2010 09:51:42 +0100 Subject: [PATCH 415/503] * fs/reiserfs.c (grub_reiserfs_iterate_dir): Zero out first byte of entry_name also for entries without stat blocks (e.g. ".."); fixes corruption of the first entry in a directory. --- ChangeLog | 6 ++++++ fs/reiserfs.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 108379321..714aa308f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-06 Colin Watson + + * fs/reiserfs.c (grub_reiserfs_iterate_dir): Zero out first byte of + entry_name also for entries without stat blocks (e.g. ".."); fixes + corruption of the first entry in a directory. + 2010-07-06 Colin Watson * util/grub.d/00_header.in: Process GRUB_THEME and GRUB_BACKGROUND diff --git a/fs/reiserfs.c b/fs/reiserfs.c index 5acd339c5..e92279554 100644 --- a/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -929,7 +929,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, "Warning : %s has no stat block !\n", entry_name); grub_free (entry_item); - continue; + goto next; } } if (hook (entry_name, entry_type, entry_item)) @@ -940,6 +940,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, goto found; } +next: *entry_name = 0; /* Make sure next entry name (which is just before this one in disk order) stops before the current one. */ From 29d7e783d2499ba439126a5026260451f39d0eed Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 6 Jul 2010 14:53:55 +0530 Subject: [PATCH 416/503] * bus/usb/usbhub.c: #include time.h header. --- ChangeLog | 4 ++++ bus/usb/usbhub.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 714aa308f..4219dab75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-06 BVK Chaitanya + + * bus/usb/usbhub.c: #include time.h header. + 2010-07-06 Colin Watson * fs/reiserfs.c (grub_reiserfs_iterate_dir): Zero out first byte of diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 034ccbe8d..2bbc850d0 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -21,6 +21,7 @@ #include #include #include +#include /* USB Supports 127 devices, with device 0 as special case. */ static struct grub_usb_device *grub_usb_devs[128]; From 5357687a559895b5eec6c24756451e5d4d92145a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 6 Jul 2010 15:10:36 +0100 Subject: [PATCH 417/503] * util/deviceiter.c (grub_util_iterate_devices): Skip MD devices, which we expect to be handled by upper layers. --- ChangeLog | 5 +++++ util/deviceiter.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4219dab75..a37ac98f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-06 Colin Watson + + * util/deviceiter.c (grub_util_iterate_devices): Skip MD devices, + which we expect to be handled by upper layers. + 2010-07-06 BVK Chaitanya * bus/usb/usbhub.c: #include time.h header. diff --git a/util/deviceiter.c b/util/deviceiter.c index 64d1cae87..bbcc00a91 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -523,6 +523,9 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), later. */ if (strncmp (entry->d_name, "dm-", sizeof ("dm-") - 1) == 0) continue; + /* Skip RAID entries; they are handled by upper layers. */ + if (strncmp (entry->d_name, "md-", sizeof ("md-") - 1) == 0) + continue; if (names_len >= names_max) { names_max *= 2; From 1e54546914014193c64757b1b58f6a01ee96a28e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 6 Jul 2010 18:31:45 +0100 Subject: [PATCH 418/503] * term/gfxterm.c (repaint_schedulded): Rename to ... (repaint_scheduled): ... this. Update all callers. (repaint_was_schedulded): Rename to ... (repaint_was_scheduled): ... this. Update all callers. --- ChangeLog | 7 +++++++ term/gfxterm.c | 16 ++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index a37ac98f1..9d2210b30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-07-06 Colin Watson + + * term/gfxterm.c (repaint_schedulded): Rename to ... + (repaint_scheduled): ... this. Update all callers. + (repaint_was_schedulded): Rename to ... + (repaint_was_scheduled): ... this. Update all callers. + 2010-07-06 Colin Watson * util/deviceiter.c (grub_util_iterate_devices): Skip MD devices, diff --git a/term/gfxterm.c b/term/gfxterm.c index a1886f7e8..44f6b191a 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -118,8 +118,8 @@ void (*grub_gfxterm_decorator_hook) (void) = NULL; static struct grub_gfxterm_window window; static struct grub_virtual_screen virtual_screen; static grub_gfxterm_repaint_callback_t repaint_callback; -static int repaint_schedulded = 0; -static int repaint_was_schedulded = 0; +static int repaint_scheduled = 0; +static int repaint_was_scheduled = 0; static void destroy_window (void); @@ -278,7 +278,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, void grub_gfxterm_schedule_repaint (void) { - repaint_schedulded = 1; + repaint_scheduled = 1; } grub_err_t @@ -510,7 +510,7 @@ dirty_region_reset (void) dirty_region.top_left_y = -1; dirty_region.bottom_right_x = -1; dirty_region.bottom_right_y = -1; - repaint_was_schedulded = 0; + repaint_was_scheduled = 0; } static int @@ -530,14 +530,14 @@ dirty_region_add (int x, int y, unsigned int width, unsigned int height) if ((width == 0) || (height == 0)) return; - if (repaint_schedulded) + if (repaint_scheduled) { x = virtual_screen.offset_x; y = virtual_screen.offset_y; width = virtual_screen.width; height = virtual_screen.height; - repaint_schedulded = 0; - repaint_was_schedulded = 1; + repaint_scheduled = 0; + repaint_was_scheduled = 1; } if (dirty_region_is_empty ()) @@ -586,7 +586,7 @@ dirty_region_redraw (void) width = dirty_region.bottom_right_x - x + 1; height = dirty_region.bottom_right_y - y + 1; - if (repaint_was_schedulded && grub_gfxterm_decorator_hook) + if (repaint_was_scheduled && grub_gfxterm_decorator_hook) grub_gfxterm_decorator_hook (); redraw_screen_rect (x, y, width, height); From 0b0f9620f2257c3ed44ddaff4b99d8b2d369ea57 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 6 Jul 2010 19:27:55 +0100 Subject: [PATCH 419/503] * conf/common.rmk (grub_probe_SOURCES): Add disk/raid5_recover.c and disk/raid6_recover.c. * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise. --- ChangeLog | 7 +++++++ conf/common.rmk | 3 ++- conf/i386-pc.rmk | 3 ++- conf/sparc64-ieee1275.rmk | 3 ++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d2210b30..91f48f0d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-07-06 Colin Watson + + * conf/common.rmk (grub_probe_SOURCES): Add disk/raid5_recover.c + and disk/raid6_recover.c. + * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise. + 2010-07-06 Colin Watson * term/gfxterm.c (repaint_schedulded): Rename to ... diff --git a/conf/common.rmk b/conf/common.rmk index 1af14f7fd..f92e5bc4c 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -38,7 +38,8 @@ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \ partmap/sun.c partmap/sunpc.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 + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/lvm.c grub_probe_init.c ifeq ($(enable_grub_fstest), yes) bin_UTILITIES += grub-fstest diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 96058e807..c157aaf01 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -78,7 +78,8 @@ grub_setup_SOURCES = gnulib/progname.c util/i386/pc/grub-setup.c \ partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ partmap/gpt.c \ \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/lvm.c \ util/raid.c util/lvm.c \ grub_setup_init.c diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index cb6b070a1..d343ac349 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -62,7 +62,8 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c \ partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c util/raid.c \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/lvm.c util/raid.c \ util/lvm.c gnulib/progname.c grub_setup_init.c # For grub-ofpathname. From f7bf0918aae95cfdb4495335d0c662e4f633993d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 7 Jul 2010 14:12:16 +0100 Subject: [PATCH 420/503] * term/gfxterm.c (grub_gfxterm_background_image_cmd): Fix indentation. --- ChangeLog | 5 ++++ term/gfxterm.c | 70 +++++++++++++++++++++++++------------------------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91f48f0d1..e4b5143d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-07 Colin Watson + + * term/gfxterm.c (grub_gfxterm_background_image_cmd): Fix + indentation. + 2010-07-06 Colin Watson * conf/common.rmk (grub_probe_SOURCES): Add disk/raid5_recover.c diff --git a/term/gfxterm.c b/term/gfxterm.c index 44f6b191a..bf9705abd 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -1134,44 +1134,44 @@ grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), /* 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; + /* Try to load new one. */ + grub_video_bitmap_load (&bitmap, args[0]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; - /* Determine if the bitmap should be scaled to fit the screen. */ - if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set - || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg, - "stretch") == 0) + /* Determine if the bitmap should be scaled to fit the screen. */ + if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set + || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg, + "stretch") == 0) + { + if (window.width != grub_video_bitmap_get_width (bitmap) + || window.height != grub_video_bitmap_get_height (bitmap)) + { + struct grub_video_bitmap *scaled_bitmap; + grub_video_bitmap_create_scaled (&scaled_bitmap, + window.width, + window.height, + bitmap, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + if (grub_errno == GRUB_ERR_NONE) + { + /* Replace the original bitmap with the scaled one. */ + grub_video_bitmap_destroy (bitmap); + bitmap = scaled_bitmap; + } + } + } + + /* If bitmap was loaded correctly, display it. */ + if (bitmap) { - if (window.width != grub_video_bitmap_get_width (bitmap) - || window.height != grub_video_bitmap_get_height (bitmap)) - { - struct grub_video_bitmap *scaled_bitmap; - grub_video_bitmap_create_scaled (&scaled_bitmap, - window.width, - window.height, - bitmap, - GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); - if (grub_errno == GRUB_ERR_NONE) - { - /* Replace the original bitmap with the scaled one. */ - grub_video_bitmap_destroy (bitmap); - bitmap = scaled_bitmap; - } - } + /* Determine bitmap dimensions. */ + bitmap_width = grub_video_bitmap_get_width (bitmap); + bitmap_height = grub_video_bitmap_get_height (bitmap); + + /* Mark whole screen as dirty. */ + dirty_region_add (0, 0, window.width, window.height); } - - /* 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_height (bitmap); - - /* Mark whole screen as dirty. */ - dirty_region_add (0, 0, window.width, window.height); - } } /* All was ok. */ From becce1b16a92a81f57ef1db3d02f53d3106907e1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 7 Jul 2010 17:51:26 +0200 Subject: [PATCH 421/503] * tests/util/grub-shell.in: Remove bashisms and declare as sh script. --- ChangeLog | 4 ++++ tests/util/grub-shell.in | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4b5143d4..789ebd391 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-07 Vladimir Serbinenko + + * tests/util/grub-shell.in: Remove bashisms and declare as sh script. + 2010-07-07 Colin Watson * term/gfxterm.c (grub_gfxterm_background_image_cmd): Fix diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 17da6c8c0..2cd256131 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -1,4 +1,4 @@ -#! /bin/bash -e +#! /bin/sh -e # Run GRUB script in a Qemu instance # Copyright (C) 2009,2010 Free Software Foundation, Inc. @@ -94,7 +94,7 @@ done if [ "x${source}" = x ] ; then tmpfile=`mktemp` - while read; do + while read REPLY; do echo $REPLY >> ${tmpfile} done source=${tmpfile} From 1b43dba911d92eb3f4fe9e9e8c3a588d893e077f Mon Sep 17 00:00:00 2001 From: starous Date: Thu, 8 Jul 2010 22:54:35 +0200 Subject: [PATCH 422/503] USB hot-plugging --- bus/usb/ohci.c | 81 +++++++++------ bus/usb/uhci.c | 11 ++- bus/usb/usb.c | 23 +++-- bus/usb/usbhub.c | 213 ++++++++++++++++++++++++++++++++++++---- include/grub/usb.h | 4 +- include/grub/usbtrans.h | 2 + 6 files changed, 271 insertions(+), 63 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index fed82d129..36bb5dd44 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -148,6 +148,7 @@ typedef enum #define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5) #define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) +#define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16) #define GRUB_OHCI_CTRL_EDS 16 #define GRUB_OHCI_BULK_EDS 16 #define GRUB_OHCI_TDS 256 @@ -420,23 +421,8 @@ grub_ohci_pci_iter (grub_pci_device_t dev, (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) | GRUB_OHCI_RHUB_PORT_ALL_POWERED); - /* Wait for stable power (100ms) and stable attachment (100ms) */ - /* I.e. minimum wait time should be probably 200ms. */ - /* We assume that device is attached when ohci is loaded. */ - /* Some devices take long time to power-on or indicate attach. */ - /* Here is some experimental value which should probably mostly work. */ - /* Cameras with manual USB mode selection and maybe some other similar - * devices will not work in some cases - they are repowered during - * ownership change and then they are starting slowly and mostly they - * are wanting select proper mode again... - * The same situation can be on computers where BIOS not set-up OHCI - * to be at least powered USB bus (maybe it is Yeelong case...?) - * Possible workaround could be for example some prompt - * for user with confirmation of proper USB device connection. - * Another workaround - "rmmod usbms", "rmmod ohci", proper start - * and configuration of USB device and then "insmod ohci" - * and "insmod usbms". */ - grub_millisleep (500); + /* Now we have hot-plugging, we need to wait for stable power only */ + grub_millisleep (100); /* Link to ohci now that initialisation is successful. */ o->next = ohci; @@ -998,6 +984,15 @@ grub_ohci_transfer (grub_usb_controller_t dev, } } + /* Even if we have "good" OHCI, in some cases + * tderr_phys can be zero, check it */ + else if ( !tderr_phys ) + { /* Retired TD with error should be previous TD to ED->td_head */ + tderr_phys = GRUB_OHCI_TD_PHYS2VIRT (o, + grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf ) + ->prev_td_phys; + } + /* Prepare pointer to last processed TD and get error code */ tderr_virt = GRUB_OHCI_TD_PHYS2VIRT (o, tderr_phys); /* Set index of last processed TD */ @@ -1095,8 +1090,6 @@ grub_ohci_transfer (grub_usb_controller_t dev, break; } - /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ - ed_virt->td_head = ed_virt->td_tail & ~0xf; } else if (err_unrec) @@ -1117,7 +1110,6 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); /* Misc. resets. */ - ed_virt->td_head = ed_virt->td_tail & ~0xf; /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ o->hcca->donehead = 0; grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); @@ -1160,10 +1152,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, else transfer->last_trans = -1; - /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ - ed_virt->td_head = ed_virt->td_tail & ~0xf; } + /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ + ed_virt->td_head = grub_cpu_to_le32 ( grub_le_to_cpu32 ( + ed_virt->td_tail) & ~0xf); + /* At this point always should be: * ED has skip bit set and halted or empty or after next SOF, * i.e. it is safe to free all TDs except last not processed @@ -1198,10 +1192,28 @@ grub_ohci_portstatus (grub_usb_controller_t dev, unsigned int port, unsigned int enable) { struct grub_ohci *o = (struct grub_ohci *) dev->data; + grub_uint64_t endtime; grub_dprintf ("ohci", "begin of portstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); + if (!enable) /* We don't need reset port */ + { + /* Disable the port and wait for it. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_CLEAR_PORT_ENABLE); + endtime = grub_get_time_ms () + 1000; + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port) + & (1 << 1))) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, "OHCI Timed out - disable"); + + grub_dprintf ("ohci", "end of portstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); + return GRUB_ERR_NONE; + } + + /* Reset the port */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, GRUB_OHCI_SET_PORT_RESET); grub_millisleep (50); /* For root hub should be nominaly 50ms */ @@ -1211,14 +1223,21 @@ grub_ohci_portstatus (grub_usb_controller_t dev, GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE); grub_millisleep (10); - if (enable) - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_SET_PORT_ENABLE); - else - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_CLEAR_PORT_ENABLE); + /* Enable the port and wait for it. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_ENABLE); + endtime = grub_get_time_ms () + 1000; + while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port) + & (1 << 1))) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, "OHCI Timed out - enable"); + grub_millisleep (10); + /* Reset bit Connect Status Change */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_RESET_CONNECT_CHANGE); + grub_dprintf ("ohci", "end of portstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); @@ -1226,7 +1245,7 @@ grub_ohci_portstatus (grub_usb_controller_t dev, } static grub_usb_speed_t -grub_ohci_detect_dev (grub_usb_controller_t dev, int port) +grub_ohci_detect_dev (grub_usb_controller_t dev, int port, int *changed) { struct grub_ohci *o = (struct grub_ohci *) dev->data; grub_uint32_t status; @@ -1235,6 +1254,9 @@ grub_ohci_detect_dev (grub_usb_controller_t dev, int port) grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status); + /* Connect Status Change bit - it detects change of connection */ + *changed = ((status & GRUB_OHCI_RESET_CONNECT_CHANGE) != 0); + if (! (status & 1)) return GRUB_USB_SPEED_NONE; else if (status & (1 << 9)) @@ -1253,7 +1275,6 @@ grub_ohci_hubports (grub_usb_controller_t dev) grub_dprintf ("ohci", "root hub ports=%d\n", portinfo & 0xFF); - /* The root hub has exactly two ports. */ return portinfo & 0xFF; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index e85f07a6f..efdf3aceb 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -644,10 +644,14 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_dprintf ("uhci", "waiting for the port to be enabled\n"); endtime = grub_get_time_ms () + 1000; - while (! (grub_uhci_readreg16 (u, reg) & (1 << 2))) + while (! ((status = grub_uhci_readreg16 (u, reg)) & (1 << 2))) if (grub_get_time_ms () > endtime) return grub_error (GRUB_ERR_IO, "UHCI Timed out"); + /* Reset bit Connect Status Change */ + grub_uhci_writereg16 (u, reg, status | (1 << 1)); + + /* Read final port status */ status = grub_uhci_readreg16 (u, reg); grub_dprintf ("uhci", ">3detect=0x%02x\n", status); @@ -656,7 +660,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, } static grub_usb_speed_t -grub_uhci_detect_dev (grub_usb_controller_t dev, int port) +grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed) { struct grub_uhci *u = (struct grub_uhci *) dev->data; int reg; @@ -676,6 +680,9 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port) grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port); + /* Connect Status Change bit - it detects change of connection */ + *changed = ((status & (1 << 1)) != 0); + if (! (status & 1)) return GRUB_USB_SPEED_NONE; else if (status & (1 << 8)) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 4f6f9e54c..f6a0a8b56 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -225,6 +225,20 @@ grub_usb_device_initialize (grub_usb_device_t dev) } } + return GRUB_USB_ERR_NONE; + + fail: + + for (i = 0; i < 8; i++) + grub_free (dev->config[i].descconf); + + return err; +} + +void grub_usb_device_attach (grub_usb_device_t dev) +{ + int i; + /* XXX: Just check configuration 0 for now. */ for (i = 0; i < dev->config[0].descconf->numif; i++) { @@ -243,15 +257,6 @@ grub_usb_device_initialize (grub_usb_device_t dev) if (interf->class == desc->class && desc->hook (dev, 0, i)) dev->config[0].interf[i].attached = 1; } - - return GRUB_USB_ERR_NONE; - - fail: - - for (i = 0; i < 8; i++) - grub_free (dev->config[i].descconf); - - return err; } void diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index f50418069..6c14f4b8d 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -23,8 +23,10 @@ #include #include +#define GRUB_USBHUB_MAX_DEVICES 128 + /* USB Supports 127 devices, with device 0 as special case. */ -static struct grub_usb_device *grub_usb_devs[128]; +static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES]; struct grub_usb_hub { @@ -44,6 +46,7 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed) { grub_usb_device_t dev; int i; + grub_usb_err_t err; dev = grub_zalloc (sizeof (struct grub_usb_device)); if (! dev) @@ -52,31 +55,51 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed) dev->controller = *controller; dev->speed = speed; - grub_usb_device_initialize (dev); + err = grub_usb_device_initialize (dev); + if (err) + { + grub_free (dev); + return NULL; + } /* Assign a new address to the device. */ - for (i = 1; i < 128; i++) + for (i = 1; i < GRUB_USBHUB_MAX_DEVICES; i++) { if (! grub_usb_devs[i]) break; } - if (i == 128) + if (i == GRUB_USBHUB_MAX_DEVICES) { grub_error (GRUB_ERR_IO, "can't assign address to USB device"); + for (i = 0; i < 8; i++) + grub_free (dev->config[i].descconf); + grub_free (dev); 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); + err = 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); + if (err) + { + for (i = 0; i < 8; i++) + grub_free (dev->config[i].descconf); + grub_free (dev); + return NULL; + } dev->addr = i; dev->initialized = 1; grub_usb_devs[i] = dev; + /* Wait "recovery interval", spec. says 2ms */ + grub_millisleep (2); + + grub_usb_device_attach (dev); + return dev; } @@ -144,7 +167,7 @@ grub_usb_add_hub (grub_usb_device_t dev) if (err) continue; grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status); - + /* If connected, reset and enable the port. */ if (status & GRUB_USB_HUB_STATUS_CONNECTED) { @@ -191,7 +214,22 @@ grub_usb_add_hub (grub_usb_device_t dev) (grub_get_time_ms() < timeout) ); if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) ) continue; + + /* Wait a recovery time after reset, spec. says 10ms */ + grub_millisleep (10); + /* Do reset of connection change bit */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_CONNECTED, + i, 0, 0); + /* Just ignore the device if the Hub reports some error */ + if (err) + continue; + grub_dprintf ("usb", "Hub port - cleared connection change\n"); + /* Add the device and assign a device address to it. */ grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i); next_dev = grub_usb_hub_add_dev (&dev->controller, speed); @@ -239,6 +277,7 @@ grub_usb_root_hub (grub_usb_controller_t controller) { int i; struct grub_usb_hub *hub; + int changed=0; hub = grub_malloc (sizeof (*hub)); if (!hub) @@ -248,7 +287,10 @@ grub_usb_root_hub (grub_usb_controller_t controller) hubs = hub; hub->controller = grub_malloc (sizeof (*controller)); if (!hub->controller) - return GRUB_USB_ERR_INTERNAL; + { + grub_free (hub); + return GRUB_USB_ERR_INTERNAL; + } grub_memcpy (hub->controller, controller, sizeof (*controller)); hub->dev = 0; @@ -258,13 +300,15 @@ grub_usb_root_hub (grub_usb_controller_t controller) hub->speed = grub_malloc (sizeof (hub->speed[0]) * hub->nports); if (!hub->speed) { + grub_free (hub->controller); grub_free (hub); return GRUB_USB_ERR_INTERNAL; } for (i = 0; i < hub->nports; i++) { - hub->speed[i] = controller->dev->detect_dev (hub->controller, i); + hub->speed[i] = controller->dev->detect_dev (hub->controller, i, + &changed); if (hub->speed[i] != GRUB_USB_SPEED_NONE) attach_root_port (hub->controller, i, hub->speed[i]); @@ -273,30 +317,157 @@ grub_usb_root_hub (grub_usb_controller_t controller) return GRUB_USB_ERR_NONE; } +static void +poll_nonroot_hub (grub_usb_device_t dev) +{ + struct grub_usb_usb_hubdesc hubdesc; + grub_err_t err; + int i; + grub_uint64_t timeout; + grub_usb_device_t next_dev; + + err = 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); + if (err) + return; + + /* 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_GET_STATUS, + 0, i, sizeof (status), (char *) &status); + /* Just ignore the device if the Hub does not report the + status. */ + if (err) + continue; + + /* Connected and status of connection changed ? */ + if ((status & GRUB_USB_HUB_STATUS_CONNECTED) + && (status & GRUB_USB_HUB_STATUS_C_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. + * Now do reset of port. */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_RESET, + i, 0, 0); + /* If the Hub does not cooperate for this port, just skip + the port. */ + if (err) + continue; + + /* Wait for reset procedure done */ + timeout = grub_get_time_ms () + 1000; + do + { + /* 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_GET_STATUS, + 0, i, sizeof (status), (char *) &status); + } + while (!err && + !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) && + (grub_get_time_ms() < timeout) ); + if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) ) + continue; + + /* Wait a recovery time after reset, spec. says 10ms */ + grub_millisleep (10); + + /* Do reset of connection change bit */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_CONNECTED, + i, 0, 0); + /* Just ignore the device if the Hub reports some error */ + if (err) + continue; + + /* Add the device and assign a device address to it. */ + next_dev = grub_usb_hub_add_dev (&dev->controller, speed); + if (! next_dev) + continue; + + /* If the device is a Hub, scan it for more devices. */ + if (next_dev->descdev.class == 0x09) + grub_usb_add_hub (next_dev); + } + } + + return; +} + void grub_usb_poll_devices (void) { struct grub_usb_hub *hub; + int i; for (hub = hubs; hub; hub = hub->next) { - int i; + int changed=0; /* Do we have to recheck number of ports? */ + /* No, it should be never changed, it should be constant. */ for (i = 0; i < hub->nports; i++) { grub_usb_speed_t speed; - speed = hub->controller->dev->detect_dev (hub->controller, i); + speed = hub->controller->dev->detect_dev (hub->controller, i, + &changed); - if (speed == hub->speed[i]) - continue; + if (speed != GRUB_USB_SPEED_NONE) + { + if (changed) + attach_root_port (hub->controller, i, speed); + } - if (hub->speed[i] == GRUB_USB_SPEED_NONE - && speed != GRUB_USB_SPEED_NONE) - attach_root_port (hub->controller, i, speed); + /* XXX: There should be also handling + * of disconnected devices. */ + hub->speed[i] = speed; } } + + /* We should check changes of non-root hubs too. */ + for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) + { + grub_usb_device_t dev = grub_usb_devs[i]; + + if (dev && dev->descdev.class == 0x09) + { + poll_nonroot_hub (dev); + } + } + } int @@ -304,7 +475,7 @@ grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) { int i; - for (i = 0; i < 128; i++) + for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) { if (grub_usb_devs[i]) { diff --git a/include/grub/usb.h b/include/grub/usb.h index 7c9dba12a..3c17318fc 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -104,7 +104,7 @@ struct grub_usb_controller_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); + grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port, int *changed); /* The next host controller. */ struct grub_usb_controller_dev *next; @@ -229,4 +229,6 @@ void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc); void grub_usb_poll_devices (void); +void grub_usb_device_attach (grub_usb_device_t dev); + #endif /* GRUB_USB_H */ diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 8f49c246f..e68698c1d 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -93,10 +93,12 @@ typedef struct grub_usb_transfer *grub_usb_transfer_t; #define GRUB_USB_HUB_FEATURE_PORT_RESET 0x04 #define GRUB_USB_HUB_FEATURE_PORT_POWER 0x08 +#define GRUB_USB_HUB_FEATURE_C_CONNECTED 0x10 #define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) #define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) #define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10) +#define GRUB_USB_HUB_STATUS_C_CONNECTED (1 << 16) #define GRUB_USB_HUB_STATUS_C_PORT_RESET (1 << 20) struct grub_usb_packet_setup From 3eaac1a13e88b5f84d4d322c55c4e3985ec52b07 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Jul 2010 02:15:49 +0200 Subject: [PATCH 423/503] * util/grub-mkrescue.in: Don't use tar GNU-ism since it's not necessary in this context. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 789ebd391..567736b39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-10 Vladimir Serbinenko + + * util/grub-mkrescue.in: Don't use tar GNU-ism since it's not necessary + in this context. + 2010-07-07 Vladimir Serbinenko * tests/util/grub-shell.in: Remove bashisms and declare as sh script. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 3bfbbddd4..e498acee7 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -211,7 +211,7 @@ EOF echo "source /boot/grub/grub.cfg") \ > ${iso9660_dir}/boot/grub/${platform}/grub.cfg - tar -C ${memdisk_dir} -cf ${memdisk_img} boot + (cd "${memdisk_dir}"; tar -cf - boot) > "${memdisk_img}" rm -rf ${memdisk_dir} $grub_mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ search iso9660 configfile normal memdisk tar $4 From 249975ba6b1439f385078c4b874505eb585207f8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Jul 2010 02:23:48 +0200 Subject: [PATCH 424/503] * normal/term.c (put_glyphs_terminal): Fix state->num_lines counting. Reported and tested by: Colin Watson. --- ChangeLog | 5 +++++ normal/term.c | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 567736b39..35ac24639 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-10 Vladimir Serbinenko + + * normal/term.c (put_glyphs_terminal): Fix state->num_lines counting. + Reported and tested by: Colin Watson. + 2010-07-10 Vladimir Serbinenko * util/grub-mkrescue.in: Don't use tar GNU-ism since it's not necessary diff --git a/normal/term.c b/normal/term.c index 46ca95843..4f5779abe 100644 --- a/normal/term.c +++ b/normal/term.c @@ -616,16 +616,18 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual, if (visual_ptr->base == '\n') grub_print_spaces (term, margin_right); putglyph (visual_ptr, term); - if (state && ++state->num_lines - >= (grub_ssize_t) grub_term_height (term) - 2) - { - state->backlog_glyphs = visual_ptr + 1; - state->backlog_len = visual_len - (visual - visual_ptr) - 1; - return 1; - } - if (visual_ptr->base == '\n') - grub_print_spaces (term, margin_left); + { + if (state && ++state->num_lines + >= (grub_ssize_t) grub_term_height (term) - 2) + { + state->backlog_glyphs = visual_ptr + 1; + state->backlog_len = visual_len - (visual - visual_ptr) - 1; + return 1; + } + + grub_print_spaces (term, margin_left); + } grub_free (visual_ptr->combining); } return 0; From 5bc24388fb151cf3547027a1ed0d0a62e9c7202d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Jul 2010 02:40:41 +0200 Subject: [PATCH 425/503] * commands/help.c (grub_cmd_help): Fix a typo. --- ChangeLog | 4 ++++ commands/help.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 35ac24639..a8a6abcae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-10 Vladimir Serbinenko + + * commands/help.c (grub_cmd_help): Fix a typo. + 2010-07-10 Vladimir Serbinenko * normal/term.c (put_glyphs_terminal): Fix state->num_lines counting. diff --git a/commands/help.c b/commands/help.c index 7ccfc4fac..e7d108c33 100644 --- a/commands/help.c +++ b/commands/help.c @@ -115,7 +115,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) grub_arg_show_help ((grub_extcmd_t) cmd->data); else - grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), + grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary), _(cmd->description)); } } From 4274c30fbca588313f224c869dc97afcbbecb9f5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Jul 2010 02:59:33 +0200 Subject: [PATCH 426/503] =?UTF-8?q?=09Restructure=20SCSI=20.id=20handling.?= =?UTF-8?q?=20=09Reported=20and=20tested=20by:=20Ale=C5=A1=20Nesrsta.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * disk/ata.c (grub_atapi_close): Removed. All users updated. (grub_atapi_dev): Changed .name to "ata". New field .id. * disk/usbms.c (grub_usbms_close): Removed. All users updated. (grub_usbms_dev): New field .id. * disk/scsi.c (grub_scsi_iterate): Generate name. (grub_scsi_open): Parse name. * include/grub/scsi.h (grub_make_scsi_id): New function. (grub_scsi_dev): Change iterate and open to number instead of naming busses. All users updated. (grub_scsi): Remove name. Add .bus. --- ChangeLog | 16 +++++++++++ disk/ata.c | 28 +++++-------------- disk/scsi.c | 65 +++++++++++++++++++++++++++++---------------- disk/usbms.c | 33 ++++------------------- include/grub/scsi.h | 28 +++++++++++++++---- 5 files changed, 93 insertions(+), 77 deletions(-) diff --git a/ChangeLog b/ChangeLog index a8a6abcae..126285a58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-07-10 Vladimir Serbinenko + + Restructure SCSI .id handling. + Reported and tested by: Aleš Nesrsta. + + * disk/ata.c (grub_atapi_close): Removed. All users updated. + (grub_atapi_dev): Changed .name to "ata". New field .id. + * disk/usbms.c (grub_usbms_close): Removed. All users updated. + (grub_usbms_dev): New field .id. + * disk/scsi.c (grub_scsi_iterate): Generate name. + (grub_scsi_open): Parse name. + * include/grub/scsi.h (grub_make_scsi_id): New function. + (grub_scsi_dev): Change iterate and open to number instead of naming + busses. All users updated. + (grub_scsi): Remove name. Add .bus. + 2010-07-10 Vladimir Serbinenko * commands/help.c (grub_cmd_help): Fix a typo. diff --git a/disk/ata.c b/disk/ata.c index 1b55ee680..cfd58a6d5 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -768,14 +768,12 @@ static struct grub_disk_dev grub_atadisk_dev = /* ATAPI code. */ static int -grub_atapi_iterate (int (*hook) (const char *name, int luns)) +grub_atapi_iterate (int (*hook) (int bus, int luns)) { struct grub_ata_device *dev; for (dev = grub_ata_devices; dev; dev = dev->next) { - char devname[10]; - grub_err_t err; err = check_device (dev); @@ -785,13 +783,10 @@ grub_atapi_iterate (int (*hook) (const char *name, int luns)) continue; } - grub_snprintf (devname, sizeof (devname), - "ata%d", dev->port * 2 + dev->device); - if (! dev->atapi) continue; - if (hook (devname, 1)) + if (hook (dev->port * 2 + dev->device, 1)) return 1; } @@ -851,7 +846,7 @@ grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)), } static grub_err_t -grub_atapi_open (const char *name, struct grub_scsi *scsi) +grub_atapi_open (int devnum, struct grub_scsi *scsi) { struct grub_ata_device *dev; struct grub_ata_device *devfnd = 0; @@ -859,18 +854,14 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) for (dev = grub_ata_devices; dev; dev = dev->next) { - char devname[10]; - grub_snprintf (devname, sizeof (devname), - "ata%d", dev->port * 2 + dev->device); - - if (!grub_strcmp (devname, name)) + if (dev->port * 2 + dev->device == devnum) { devfnd = dev; break; } } - grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name); + grub_dprintf ("ata", "opening ATAPI dev `ata%d'\n", devnum); if (! devfnd) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); @@ -887,18 +878,13 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) 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", + .name = "ata", + .id = GRUB_SCSI_SUBSYSTEM_ATAPI, .iterate = grub_atapi_iterate, .open = grub_atapi_open, - .close = grub_atapi_close, .read = grub_atapi_read, .write = grub_atapi_write }; diff --git a/disk/scsi.c b/disk/scsi.c index 5d3e50966..5f04d9ef7 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -318,15 +318,24 @@ grub_scsi_iterate (int (*hook) (const char *name)) { grub_scsi_dev_t p; - auto int scsi_iterate (const char *name, int luns); + auto int scsi_iterate (int bus, int luns); - int scsi_iterate (const char *name, int luns) + int scsi_iterate (int bus, int luns) { int i; /* In case of a single LUN, just return `usbX'. */ if (luns == 1) - return hook (name); + { + char *sname; + int ret; + sname = grub_xasprintf ("%s%d", p->name, bus); + if (!sname) + return 1; + ret = hook (sname); + grub_free (sname); + return ret; + } /* In case of multiple LUNs, every LUN will get a prefix to distinguish it. */ @@ -334,7 +343,7 @@ grub_scsi_iterate (int (*hook) (const char *name)) { char *sname; int ret; - sname = grub_xasprintf ("%s%c", name, 'a' + i); + sname = grub_xasprintf ("%s%d%c", p->name, bus, 'a' + i); if (!sname) return 1; ret = hook (sname); @@ -358,37 +367,46 @@ 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; + int lun, bus; grub_uint64_t maxtime; + const char *nameend; + + nameend = name + grub_strlen (name) - 1; + /* Try to detect a LUN ('a'-'z'), otherwise just use the first + LUN. */ + if (nameend >= name && *nameend >= 'a' && *nameend <= 'z') + { + lun = *nameend - 'a'; + nameend--; + } + else + lun = 0; + + while (nameend >= name && grub_isdigit (*nameend)) + nameend--; + + if (!nameend[1] || !grub_isdigit (nameend[1])) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk"); + + bus = grub_strtoul (nameend + 1, 0, 0); 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)) + if (grub_strncmp (p->name, name, nameend - name) != 0) continue; - disk->id = (unsigned long) "scsi"; /* XXX */ + if (p->open (bus, scsi)) + continue; + + disk->id = grub_make_scsi_id (scsi->dev->id, bus, lun); disk->data = scsi; scsi->dev = p; scsi->lun = lun; - scsi->name = grub_strdup (name); - if (! scsi->name) - { - grub_free (scsi); - return grub_errno; - } + scsi->bus = bus; grub_dprintf ("scsi", "dev opened\n"); @@ -476,7 +494,8 @@ grub_scsi_close (grub_disk_t disk) grub_scsi_t scsi; scsi = disk->data; - scsi->dev->close (scsi); + if (scsi->dev->close) + scsi->dev->close (scsi); grub_free (scsi); } diff --git a/disk/usbms.c b/disk/usbms.c index f913ee3f7..1301791e5 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -222,22 +222,15 @@ grub_usbms_finddevs (void) static int -grub_usbms_iterate (int (*hook) (const char *name, int luns)) +grub_usbms_iterate (int (*hook) (int bus, int luns)) { grub_usbms_dev_t p; int cnt = 0; for (p = grub_usbms_dev_list; p; p = p->next) { - char *devname; - devname = grub_xasprintf ("usb%d", cnt); - - if (hook (devname, p->luns)) - { - grub_free (devname); - return 1; - } - grub_free (devname); + if (hook (cnt, p->luns)) + return 1; cnt++; } @@ -398,28 +391,18 @@ grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, } static grub_err_t -grub_usbms_open (const char *name, struct grub_scsi *scsi) +grub_usbms_open (int devnum, 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; } @@ -430,18 +413,12 @@ grub_usbms_open (const char *name, struct grub_scsi *scsi) "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", + .id = GRUB_SCSI_SUBSYSTEM_USBMS, .iterate = grub_usbms_iterate, .open = grub_usbms_open, - .close = grub_usbms_close, .read = grub_usbms_read, .write = grub_usbms_write }; diff --git a/include/grub/scsi.h b/include/grub/scsi.h index fbe4582ca..b3c60f3e8 100644 --- a/include/grub/scsi.h +++ b/include/grub/scsi.h @@ -26,16 +26,35 @@ void grub_scsi_dev_unregister (grub_scsi_dev_t dev); struct grub_scsi; +enum + { + GRUB_SCSI_SUBSYSTEM_USBMS, + GRUB_SCSI_SUBSYSTEM_ATAPI + }; + +#define GRUB_SCSI_ID_SUBSYSTEM_SHIFT 24 +#define GRUB_SCSI_ID_BUS_SHIFT 8 +#define GRUB_SCSI_ID_LUN_SHIFT 0 + +static inline grub_uint32_t +grub_make_scsi_id (int subsystem, int bus, int lun) +{ + return (subsystem << GRUB_SCSI_ID_SUBSYSTEM_SHIFT) + | (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_BUS_SHIFT); +} + struct grub_scsi_dev { /* The device name. */ const char *name; + grub_uint8_t id; + /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*iterate) (int (*hook) (const char *name, int luns)); + int (*iterate) (int (*hook) (int bus, int luns)); /* Open the device named NAME, and set up SCSI. */ - grub_err_t (*open) (const char *name, struct grub_scsi *scsi); + grub_err_t (*open) (int bus, struct grub_scsi *scsi); /* Close the scsi device SCSI. */ void (*close) (struct grub_scsi *scsi); @@ -56,15 +75,14 @@ struct grub_scsi_dev 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; + int bus; + /* Number of LUNs. */ int luns; From e4f4eafc912a6b802731ea407cd00ab8438d8446 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 10 Jul 2010 22:37:05 +0100 Subject: [PATCH 427/503] * Makefile.in (MAINTAINER_CLEANFILES): Remove unicode/UnicodeData.txt, unicode/BidiMirroring.txt, and unicode/ArabicShaping.txt again; these are inputs to autogen.sh, not outputs. --- ChangeLog | 7 +++++++ Makefile.in | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 126285a58..1fdf98bf1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-07-10 Colin Watson + + * Makefile.in (MAINTAINER_CLEANFILES): Remove + unicode/UnicodeData.txt, unicode/BidiMirroring.txt, and + unicode/ArabicShaping.txt again; these are inputs to autogen.sh, not + outputs. + 2010-07-10 Vladimir Serbinenko Restructure SCSI .id handling. diff --git a/Makefile.in b/Makefile.in index ec3b72296..ce407e0cc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -169,8 +169,7 @@ MAINTAINER_CLEANFILES = $(srcdir)/configure $(srcdir)/aclocal.m4 \ $(MKFILES) $(srcdir)/config.guess \ $(srcdir)/config.sub $(srcdir)/install-sh $(srcdir)/missing \ $(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in \ - $(srcdir)/unicode/UnicodeData.txt $(srcdir)/unicode/BidiMirroring.txt \ - $(srcdir)/unicode/ArabicShaping.txt $(srcdir)/unidata.c \ + $(srcdir)/unidata.c \ $(INFOS) # The default target. From 811b0dcab848a85b5eb8faafa8a38036041e06ff Mon Sep 17 00:00:00 2001 From: Jiro SEKIBA Date: Tue, 13 Jul 2010 11:47:30 +0200 Subject: [PATCH 428/503] * fs/nilfs2.c: fix macro NILFS_2ND_SUPER_BLOCK to calculate 2nd superblock position from partition size. --- ChangeLog | 5 +++++ fs/nilfs2.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fdf98bf1..844d9f181 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-13 Jiro SEKIBA + + * fs/nilfs2.c: fix macro NILFS_2ND_SUPER_BLOCK to calculate + 2nd superblock position from partition size. + 2010-07-10 Colin Watson * Makefile.in (MAINTAINER_CLEANFILES): Remove diff --git a/fs/nilfs2.c b/fs/nilfs2.c index 5d32f5f88..8329c01a1 100644 --- a/fs/nilfs2.c +++ b/fs/nilfs2.c @@ -52,9 +52,9 @@ /* nilfs 1st super block posission from beginning of the partition in 512 block size */ #define NILFS_1ST_SUPER_BLOCK 2 -/* nilfs 2nd super block posission from end of the partition +/* nilfs 2nd super block posission from beginning of the partition in 512 block size */ -#define NILFS_2ND_SUPER_BLOCK 8 +#define NILFS_2ND_SUPER_BLOCK(devsize) (((devsize >> 3) - 1) << 3) struct grub_nilfs2_inode { @@ -729,7 +729,7 @@ grub_nilfs2_load_sb (struct grub_nilfs2_data *data) if (partition_size != GRUB_DISK_SIZE_UNKNOWN) { /* Read second super block. */ - grub_disk_read (disk, partition_size - NILFS_2ND_SUPER_BLOCK, 0, + grub_disk_read (disk, NILFS_2ND_SUPER_BLOCK (partition_size), 0, sizeof (struct grub_nilfs2_super_block), &sb2); /* Make sure if 2nd super block is valid. */ valid[1] = grub_nilfs2_valid_sb (&sb2); From 1a1f1e67943b6c6b493a6b7a1d14a7db7c3a2a39 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 13 Jul 2010 12:20:32 +0100 Subject: [PATCH 429/503] * README: Point to the Info manual. --- ChangeLog | 4 ++++ README | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 844d9f181..595f22756 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-13 Colin Watson + + * README: Point to the Info manual. + 2010-07-13 Jiro SEKIBA * fs/nilfs2.c: fix macro NILFS_2ND_SUPER_BLOCK to calculate diff --git a/README b/README index b6c7fd6d7..b30a4b68b 100644 --- a/README +++ b/README @@ -10,5 +10,13 @@ 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. +More extensive documentation is available in the Info manual, +accessible using 'info grub' after building and installing GRUB 2. +Please look at the GRUB Wiki for testing +procedures. + +There are a number of important user-visible differences from the +first version of GRUB, now known as GRUB Legacy. For a summary, please +see: + + info grub Introduction 'Changes from GRUB Legacy' From 19563c25c1438db615543e3ff9c3c2c1111bf96a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 13 Jul 2010 12:24:07 +0100 Subject: [PATCH 430/503] * Makefile.in (.SUFFIX): Spell correctly, as ... (.SUFFIXES): ... this. Fixes bug where `make foo' (where foo is a bare module name without `.mod', e.g. `test') tried to invoke a Modula-2 compiler. --- ChangeLog | 7 +++++++ Makefile.in | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 595f22756..e894a479c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-07-13 Colin Watson + + * Makefile.in (.SUFFIX): Spell correctly, as ... + (.SUFFIXES): ... this. Fixes bug where `make foo' (where foo is a + bare module name without `.mod', e.g. `test') tried to invoke a + Modula-2 compiler. + 2010-07-13 Colin Watson * README: Point to the Info manual. diff --git a/Makefile.in b/Makefile.in index ce407e0cc..3dc7e6f19 100644 --- a/Makefile.in +++ b/Makefile.in @@ -524,8 +524,8 @@ check: all $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(SCRIPTED_TESTS) $(builddir)/$$file; \ done -.SUFFIX: -.SUFFIX: .c .o .S .d +.SUFFIXES: +.SUFFIXES: .c .o .S .d # Regenerate configure and Makefile automatically. $(srcdir)/aclocal.m4: configure.ac acinclude.m4 From 8d9a5b15e3b0f83ed26a6131a8f099a6a7dcf5ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Wed, 14 Jul 2010 11:26:17 +0200 Subject: [PATCH 431/503] Discard improperly nested partitions. --- ChangeLog | 13 ++++++++++ include/grub/partition.h | 4 +-- kern/partition.c | 56 +++++++++++++++++++++++++++++++++------- partmap/bsdlabel.c | 40 +++++++++++++++++++++++----- 4 files changed, 95 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index e894a479c..8511fa2cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-07-14 Grégoire Sutre + + * kern/partition.c (grub_partition_check_containment): New function to + check that a partition is physically contained in a parent. Since + offsets are relative (and non-negative), this reduces to checking that + the partition ends before its parent. + (grub_partition_map_probe): Discard out-of-range sub-partitions. + (grub_partition_iterate): Likewise. + * include/grub/partition.h (grub_partition_map): Slightly more detailed + comments. + * partmap/bsdlabel.c (bsdlabel_partition_map_iterate): Discard + partitions that start before their parent, and add debug printfs. + 2010-07-13 Colin Watson * Makefile.in (.SUFFIX): Spell correctly, as ... diff --git a/include/grub/partition.h b/include/grub/partition.h index a23e94e07..20705c527 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -48,7 +48,7 @@ struct grub_partition /* The partition number. */ int number; - /* The start sector. */ + /* The start sector (relative to parent). */ grub_disk_addr_t start; /* The length in sector units. */ @@ -60,7 +60,7 @@ struct grub_partition /* The index of this partition in the partition table. */ int index; - /* Parent partition map. */ + /* Parent partition (physically contains this partition). */ struct grub_partition *parent; /* The type partition map. */ diff --git a/kern/partition.c b/kern/partition.c index 2a33ac329..a1e37f675 100644 --- a/kern/partition.c +++ b/kern/partition.c @@ -23,6 +23,37 @@ grub_partition_map_t grub_partition_map_list; +/* + * Checks that disk->partition contains part. This function assumes that the + * start of part is relative to the start of disk->partition. Returns 1 if + * disk->partition is null. + */ +static int +grub_partition_check_containment (const grub_disk_t disk, + const grub_partition_t part) +{ + if (disk->partition == NULL) + return 1; + + if (part->start + part->len > disk->partition->len) + { + char *partname; + + partname = grub_partition_get_name (disk->partition); + grub_dprintf ("partition", "sub-partition %s%d of (%s,%s) ends after parent.\n", + part->partmap->name, part->number + 1, disk->name, partname); +#ifdef GRUB_UTIL + grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", + disk->name, partname, part->partmap->name, part->number + 1); +#endif + grub_free (partname); + + return 0; + } + + return 1; +} + static grub_partition_t grub_partition_map_probe (const grub_partition_map_t partmap, grub_disk_t disk, int partnum) @@ -31,20 +62,21 @@ grub_partition_map_probe (const grub_partition_map_t partmap, auto int find_func (grub_disk_t d, const grub_partition_t partition); - int find_func (grub_disk_t d __attribute__ ((unused)), + int find_func (grub_disk_t dsk, const grub_partition_t partition) { - if (partnum == partition->number) - { - p = (grub_partition_t) grub_malloc (sizeof (*p)); - if (! p) - return 1; + if (partnum != partition->number) + return 0; - grub_memcpy (p, partition, sizeof (*p)); - return 1; - } + if (!(grub_partition_check_containment (dsk, partition))) + return 0; - return 0; + p = (grub_partition_t) grub_malloc (sizeof (*p)); + if (! p) + return 1; + + grub_memcpy (p, partition, sizeof (*p)); + return 1; } partmap->iterate (disk, find_func); @@ -138,6 +170,10 @@ grub_partition_iterate (struct grub_disk *disk, const grub_partition_t partition) { struct grub_partition p = *partition; + + if (!(grub_partition_check_containment (dsk, partition))) + return 0; + p.parent = dsk->partition; dsk->partition = 0; if (hook (dsk, &p)) diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c index d28f36d07..d38a0eaf3 100644 --- a/partmap/bsdlabel.c +++ b/partmap/bsdlabel.c @@ -54,7 +54,7 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, for (p.number = 0; p.number < grub_cpu_to_le16 (label.num_partitions); - p.number++) + p.number++, pos += sizeof (struct grub_partition_bsd_entry)) { struct grub_partition_bsd_entry be; @@ -64,15 +64,43 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, if (grub_disk_read (disk, p.offset, p.index, sizeof (be), &be)) return grub_errno; - p.start = grub_le_to_cpu32 (be.offset) - delta; + p.start = grub_le_to_cpu32 (be.offset); p.len = grub_le_to_cpu32 (be.size); p.partmap = &grub_bsdlabel_partition_map; - if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED) - if (hook (disk, &p)) - return grub_errno; + grub_dprintf ("partition", + "partition %d: type 0x%x, start 0x%llx, len 0x%llx\n", + p.number, be.fs_type, + (unsigned long long) p.start, + (unsigned long long) p.len); - pos += sizeof (struct grub_partition_bsd_entry); + if (be.fs_type == GRUB_PC_PARTITION_BSD_TYPE_UNUSED) + continue; + + if (p.start < delta) + { +#ifdef GRUB_UTIL + char *partname; +#endif + grub_dprintf ("partition", + "partition %d: invalid start (found 0x%llx, wanted >= 0x%llx)\n", + p.number, + (unsigned long long) p.start, + (unsigned long long) delta); +#ifdef GRUB_UTIL + /* disk->partition != NULL as 0 < delta */ + partname = grub_partition_get_name (disk->partition); + grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", + disk->name, partname, p.partmap->name, p.number + 1); + grub_free (partname); +#endif + continue; + } + + p.start -= delta; + + if (hook (disk, &p)) + return grub_errno; } return GRUB_ERR_NONE; From 18075f6254cd47235acb173dd079a0e8a54451f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Wed, 14 Jul 2010 16:47:28 +0200 Subject: [PATCH 432/503] Fix condition in Makefile.in's LINGUAS assignment. --- ChangeLog | 4 ++++ Makefile.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8511fa2cf..99a177f66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-14 Grégoire Sutre + + * Makefile.in: Use the substituted @USE_NLS@ instead of ENABLE_NLS. + 2010-07-14 Grégoire Sutre * kern/partition.c (grub_partition_check_containment): New function to diff --git a/Makefile.in b/Makefile.in index 3dc7e6f19..39061be4d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -53,7 +53,7 @@ XGETTEXT = @XGETTEXT@ MSGMERGE = @MSGMERGE@ MSGFMT = @MSGFMT@ -ifdef ENABLE_NLS +ifeq (@USE_NLS@,yes) LINGUAS = $(shell for i in $(srcdir)/po/*.po ; do \ if test -e $$i ; then echo $$i ; fi ; \ done | sed -e "s,.*/po/\(.*\)\.po$$,\1,") From 99be513c3ba7ec9247ff29a8c2031fc8dbbaebfb Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 14 Jul 2010 16:47:45 +0100 Subject: [PATCH 433/503] * loader/powerpc/ieee1275/linux.c (grub_cmd_linux): Do not reject ET_DYN files. --- ChangeLog | 5 +++++ loader/powerpc/ieee1275/linux.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 99a177f66..835293aec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-14 Anton Blanchard + + * loader/powerpc/ieee1275/linux.c (grub_cmd_linux): Do not reject + ET_DYN files. + 2010-07-14 Grégoire Sutre * Makefile.in: Use the substituted @USE_NLS@ instead of ENABLE_NLS. diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c index 930c0cb41..6b17a47ad 100644 --- a/loader/powerpc/ieee1275/linux.c +++ b/loader/powerpc/ieee1275/linux.c @@ -220,7 +220,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (! elf) goto out; - if (elf->ehdr.ehdr32.e_type != ET_EXEC) + if (elf->ehdr.ehdr32.e_type != ET_EXEC && elf->ehdr.ehdr32.e_type != ET_DYN) { grub_error (GRUB_ERR_UNKNOWN_OS, "this ELF file is not of the right type"); From 9c17c6411aa36e72c0d5f28f651eab0297309052 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Jul 2010 00:56:38 +0200 Subject: [PATCH 434/503] Fix mismerge --- disk/usbms.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/disk/usbms.c b/disk/usbms.c index 654e40c36..0a781ccec 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -292,11 +292,15 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, goto CheckCSW; } /* Debug print of received data. */ - grub_dprintf ("usb", "First 16 bytes of received data:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[ 0], buf[ 1], buf[ 2], buf[ 3], - buf[ 4], buf[ 5], buf[ 6], buf[ 7], - buf[ 8], buf[ 9], buf[10], buf[11], - buf[12], buf[13], buf[14], buf[15]); + grub_dprintf ("usb", "buf:\n"); + if (size <= 64) + { + unsigned i; + for (i = 0; i < size; i++) + grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]); + } + else + grub_dprintf ("usb", "Too much data for debug print...\n"); } else if (size) { @@ -313,6 +317,15 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto CheckCSW; } + /* Debug print of sent data. */ + if (size <= 256) + { + unsigned i; + for (i=0; i Date: Sat, 17 Jul 2010 00:57:14 +0200 Subject: [PATCH 435/503] Use inline functions instead of macros --- bus/usb/ohci.c | 93 +++++++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 36bb5dd44..57ca24065 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -155,23 +155,44 @@ typedef enum #define GRUB_OHCI_ED_ADDR_MASK 0x7ff -#define GRUB_OHCI_ED_PHYS2VIRT(o, bulk, x) ( !(x) ? NULL : ( \ - (bulk) ? \ - (grub_ohci_ed_t)((x) - (o)->ed_bulk_addr + (grub_uint32_t)(o)->ed_bulk) \ - : \ - (grub_ohci_ed_t)((x) - (o)->ed_ctrl_addr + (grub_uint32_t)(o)->ed_ctrl) ) ) - -#define GRUB_OHCI_ED_VIRT2PHYS(o, bulk, x) ( !(x) ? 0 : ( \ - (bulk) ? \ - ((grub_uint32_t)(x) - (grub_uint32_t)(o)->ed_bulk + (o)->ed_bulk_addr) \ - : \ - ((grub_uint32_t)(x) - (grub_uint32_t)(o)->ed_ctrl + (o)->ed_ctrl_addr) ) ) +static inline grub_ohci_ed_t +grub_ohci_ed_phys2virt (struct grub_ohci *o, int bulk, grub_uint32_t x) +{ + if (!x) + return NULL; + if (bulk) + return (grub_ohci_ed_t) (x - o->ed_bulk_addr + + (grub_uint8_t *) o->ed_bulk); + return (grub_ohci_ed_t) (x - o->ed_ctrl_addr + + (grub_uint8_t *) o->ed_ctrl); +} -#define GRUB_OHCI_TD_PHYS2VIRT(o, x) ( !(x) ? NULL : \ - (grub_ohci_td_t)((x) - (o)->td_addr + (grub_uint32_t)(o)->td) ) +static grub_uint32_t +grub_ohci_virt_to_phys (struct grub_ohci *o, int bulk, grub_ohci_ed_t x) +{ + if (!x) + return 0; -#define GRUB_OHCI_TD_VIRT2PHYS(o, x) ( !(x) ? 0 : \ - ((grub_uint32_t)(x) - (grub_uint32_t)(o)->td + (o)->td_addr) ) + if (bulk) + return (grub_uint8_t *) x - (grub_uint8_t *) o->ed_bulk + o->ed_bulk_addr; + return (grub_uint8_t *) x - (grub_uint8_t *) o->ed_ctrl + o->ed_ctrl_addr; +} + +static inline grub_ohci_td_t +grub_ohci_td_phys2virt (struct grub_ohci *o, grub_uint32_t x) +{ + if (!x) + return NULL; + return (grub_ohci_td_t) (x - o->td_addr + (grub_uint8_t *) o->td); +} + +static grub_uint32_t +grub_ohci_td_virt2phys (struct grub_ohci *o, grub_ohci_td_t x) +{ + if (!x) + return 0; + return (grub_uint8_t *)x - (grub_uint8_t *)o->td + o->td_addr; +} static grub_uint32_t @@ -479,14 +500,14 @@ grub_ohci_find_ed (struct grub_ohci *o, int bulk, grub_uint32_t target) { count = GRUB_OHCI_BULK_EDS; ed = o->ed_bulk; - ed_next = GRUB_OHCI_ED_PHYS2VIRT(o, bulk, + ed_next = grub_ohci_ed_phys2virt(o, bulk, grub_le_to_cpu32 (ed->next_ed) ); } else { count = GRUB_OHCI_CTRL_EDS; ed = o->ed_ctrl; - ed_next = GRUB_OHCI_ED_PHYS2VIRT(o, bulk, + ed_next = grub_ohci_ed_phys2virt(o, bulk, grub_le_to_cpu32 (ed->next_ed) ); } @@ -500,7 +521,7 @@ grub_ohci_find_ed (struct grub_ohci *o, int bulk, grub_uint32_t target) if (ed_next && (i < count)) { ed = ed_next; - ed_next = GRUB_OHCI_ED_PHYS2VIRT(o, bulk, + ed_next = grub_ohci_ed_phys2virt(o, bulk, grub_le_to_cpu32 (ed->next_ed) ); continue; } @@ -516,7 +537,7 @@ grub_ohci_find_ed (struct grub_ohci *o, int bulk, grub_uint32_t target) * of unplugged devices. */ /* We can link new ED to previous ED safely as the new ED should * still have set skip bit. */ - ed->next_ed = grub_cpu_to_le32 ( GRUB_OHCI_ED_VIRT2PHYS (o, + ed->next_ed = grub_cpu_to_le32 ( grub_ohci_virt_to_phys (o, bulk, &ed[1])); return &ed[1]; } @@ -553,7 +574,7 @@ grub_ohci_free_tds (struct grub_ohci *o, grub_ohci_td_t td) /* Unchain first TD from previous TD if it is chained */ if (td->prev_td_phys) { - grub_ohci_td_t td_prev_virt = GRUB_OHCI_TD_PHYS2VIRT(o, + grub_ohci_td_t td_prev_virt = grub_ohci_td_phys2virt(o, td->prev_td_phys); if (td == (grub_ohci_td_t) td_prev_virt->link_td) @@ -714,12 +735,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */ /* We can set td_head only when ED is not active, i.e. * when it is newly allocated. */ - ed_virt->td_head = grub_cpu_to_le32 ( GRUB_OHCI_TD_VIRT2PHYS (o, + ed_virt->td_head = grub_cpu_to_le32 ( grub_ohci_td_virt2phys (o, td_head_virt) ); ed_virt->td_tail = ed_virt->td_head; } else - td_head_virt = GRUB_OHCI_TD_PHYS2VIRT ( o, td_head_phys ); + td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys ); /* Set TDs */ td_last_phys = td_head_phys; /* initial value to make compiler happy... */ @@ -739,7 +760,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21); /* Remember last used (processed) TD phys. addr. */ - td_last_phys = GRUB_OHCI_TD_VIRT2PHYS (o, td_current_virt); + td_last_phys = grub_ohci_td_virt2phys (o, td_current_virt); /* Allocate next TD */ td_next_virt = grub_ohci_alloc_td (o); @@ -747,7 +768,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, { if (i) /* if i==0 we have nothing to free... */ grub_ohci_free_tds (o, - GRUB_OHCI_TD_PHYS2VIRT(o, + grub_ohci_td_phys2virt(o, grub_le_to_cpu32 (td_head_virt->next_td) ) ); /* Reset head TD */ grub_memset ( (void*)td_head_virt, 0, @@ -759,9 +780,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Chain TDs */ td_current_virt->link_td = (grub_uint32_t) td_next_virt; td_current_virt->next_td = grub_cpu_to_le32 ( - GRUB_OHCI_TD_VIRT2PHYS (o, + grub_ohci_td_virt2phys (o, td_next_virt) ); - td_next_virt->prev_td_phys = GRUB_OHCI_TD_VIRT2PHYS (o, + td_next_virt->prev_td_phys = grub_ohci_td_virt2phys (o, td_current_virt); td_current_virt = td_next_virt; } @@ -777,8 +798,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, * setup sequence and we must handle it. */ ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); /* Set td_tail */ - ed_virt->td_tail = grub_cpu_to_le32 ( GRUB_OHCI_TD_VIRT2PHYS (o, - td_current_virt) ); + ed_virt->td_tail + = grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, td_current_virt)); /* Now reset skip bit */ ed_virt->target = grub_cpu_to_le32 (target); /* ed_virt->td_head = grub_cpu_to_le32 (td_head); Must not be changed, it is maintained by OHCI */ @@ -959,7 +980,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* I hope we can do it as transfer (most probably) finished OK */ } /* Prepare pointer to last processed TD */ - tderr_virt = GRUB_OHCI_TD_PHYS2VIRT (o, tderr_phys); + tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys); /* Set index of last processed TD */ if (tderr_virt) transfer->last_trans = tderr_virt->tr_index; @@ -973,12 +994,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */ { if ( tderr_phys ) /* check if tderr_phys points to TD with error */ - errcode = grub_le_to_cpu32 ( GRUB_OHCI_TD_PHYS2VIRT (o, + errcode = grub_le_to_cpu32 ( grub_ohci_td_phys2virt (o, tderr_phys)->token ) >> 28; if ( !tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */ { /* Retired TD with error should be previous TD to ED->td_head */ - tderr_phys = GRUB_OHCI_TD_PHYS2VIRT (o, + tderr_phys = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf ) ->prev_td_phys; } @@ -988,13 +1009,13 @@ grub_ohci_transfer (grub_usb_controller_t dev, * tderr_phys can be zero, check it */ else if ( !tderr_phys ) { /* Retired TD with error should be previous TD to ED->td_head */ - tderr_phys = GRUB_OHCI_TD_PHYS2VIRT (o, + tderr_phys = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf ) ->prev_td_phys; } /* Prepare pointer to last processed TD and get error code */ - tderr_virt = GRUB_OHCI_TD_PHYS2VIRT (o, tderr_phys); + tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys); /* Set index of last processed TD */ if (tderr_virt) { @@ -1142,11 +1163,11 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Now we must find last processed TD if bad_OHCI == TRUE */ if (o->bad_OHCI) { /* Retired TD with error should be previous TD to ED->td_head */ - tderr_phys = GRUB_OHCI_TD_PHYS2VIRT (o, + tderr_phys = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf) ->prev_td_phys; } - tderr_virt = GRUB_OHCI_TD_PHYS2VIRT (o, tderr_phys); + tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys); if (tderr_virt) transfer->last_trans = tderr_virt->tr_index; else @@ -1173,7 +1194,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (td_current_virt->prev_td_phys) { grub_ohci_td_t td_prev_virt - = GRUB_OHCI_TD_PHYS2VIRT (o, td_current_virt->prev_td_phys); + = grub_ohci_td_phys2virt (o, td_current_virt->prev_td_phys); td_next_virt = (grub_ohci_td_t) td_prev_virt->link_td; if (td_current_virt == td_next_virt) From 986aad56c1416ffcf738657e0dd0710b36254189 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Jul 2010 01:52:41 +0200 Subject: [PATCH 436/503] * disk/scsi.c (grub_scsi_open): Fix incorrect pointer dereference. --- ChangeLog | 4 ++++ disk/scsi.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 835293aec..3fd31efaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-17 Vladimir Serbinenko + + * disk/scsi.c (grub_scsi_open): Fix incorrect pointer dereference. + 2010-07-14 Anton Blanchard * loader/powerpc/ieee1275/linux.c (grub_cmd_linux): Do not reject diff --git a/disk/scsi.c b/disk/scsi.c index 5f04d9ef7..60192bef5 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -402,7 +402,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) if (p->open (bus, scsi)) continue; - disk->id = grub_make_scsi_id (scsi->dev->id, bus, lun); + disk->id = grub_make_scsi_id (p->id, bus, lun); disk->data = scsi; scsi->dev = p; scsi->lun = lun; From 139b714a9362ded418c3d8819c672148e554b1d2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Jul 2010 01:55:01 +0200 Subject: [PATCH 437/503] * kern/partition.c [GRUB_UTIL]: Add missing util/misc.h inclusion. * partmap/bsdlabel.c [GRUB_UTIL]: Likewise. --- ChangeLog | 5 +++++ kern/partition.c | 4 ++++ partmap/bsdlabel.c | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3fd31efaf..a367f6891 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-17 Vladimir Serbinenko + + * kern/partition.c [GRUB_UTIL]: Add missing util/misc.h inclusion. + * partmap/bsdlabel.c [GRUB_UTIL]: Likewise. + 2010-07-17 Vladimir Serbinenko * disk/scsi.c (grub_scsi_open): Fix incorrect pointer dereference. diff --git a/kern/partition.c b/kern/partition.c index a1e37f675..a2f5dd722 100644 --- a/kern/partition.c +++ b/kern/partition.c @@ -21,6 +21,10 @@ #include #include +#ifdef GRUB_UTIL +#include +#endif + grub_partition_map_t grub_partition_map_list; /* diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c index d38a0eaf3..f671f76d8 100644 --- a/partmap/bsdlabel.c +++ b/partmap/bsdlabel.c @@ -24,6 +24,10 @@ #include #include +#ifdef GRUB_UTIL +#include +#endif + static struct grub_partition_map grub_bsdlabel_partition_map; From 3222efaff353b7e49ddbca581fb1f01e51ed5d8b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Jul 2010 01:57:48 +0200 Subject: [PATCH 438/503] * include/grub/bsdlabel.h (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION): New definition. * partmap/bsdlabel.c (bsdlabel_partition_map_iterate): Use FreeBSD delta determination style. Works with most NetBSD partitions too. --- ChangeLog | 6 ++++++ include/grub/bsdlabel.h | 2 ++ partmap/bsdlabel.c | 26 ++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a367f6891..0ab95813a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-17 Vladimir Serbinenko + + * include/grub/bsdlabel.h (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION): New definition. + * partmap/bsdlabel.c (bsdlabel_partition_map_iterate): Use FreeBSD + delta determination style. Works with most NetBSD partitions too. + 2010-07-17 Vladimir Serbinenko * kern/partition.c [GRUB_UTIL]: Add missing util/misc.h inclusion. diff --git a/include/grub/bsdlabel.h b/include/grub/bsdlabel.h index d88b25353..636bd41a1 100644 --- a/include/grub/bsdlabel.h +++ b/include/grub/bsdlabel.h @@ -63,6 +63,8 @@ #define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18 #define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19 +#define GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION 2 + /* The BSD partition entry. */ struct grub_partition_bsd_entry { diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c index f671f76d8..a27b8eaec 100644 --- a/partmap/bsdlabel.c +++ b/partmap/bsdlabel.c @@ -41,9 +41,6 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, grub_disk_addr_t delta = 0; unsigned pos; - /* BSDLabel offsets are absolute even when it's embed inside partition. */ - delta = grub_partition_get_start (disk->partition); - /* Read the BSD label. */ if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, sizeof (label), &label)) @@ -53,6 +50,24 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + /* A kludge to determine a base of be.offset. */ + if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION + < grub_cpu_to_le16 (label.num_partitions)) + { + struct grub_partition_bsd_entry whole_disk_be; + + pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR + * GRUB_DISK_SECTOR_SIZE + sizeof (struct grub_partition_bsd_entry) + * GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION; + + if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE, + pos % GRUB_DISK_SECTOR_SIZE, sizeof (whole_disk_be), + &whole_disk_be)) + return grub_errno; + + delta = grub_le_to_cpu32 (whole_disk_be.offset); + } + pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR * GRUB_DISK_SECTOR_SIZE; @@ -62,6 +77,9 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, { struct grub_partition_bsd_entry be; + if (p.number == GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION) + continue; + p.offset = pos / GRUB_DISK_SECTOR_SIZE; p.index = pos % GRUB_DISK_SECTOR_SIZE; @@ -78,7 +96,7 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, (unsigned long long) p.start, (unsigned long long) p.len); - if (be.fs_type == GRUB_PC_PARTITION_BSD_TYPE_UNUSED) + if (p.len == 0) continue; if (p.start < delta) From 5771289a14bc26e3145917b79910026c6bc298b6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 17 Jul 2010 19:27:18 +0100 Subject: [PATCH 439/503] * util/import_unicode.py: Remove unnecessary imports. --- ChangeLog | 4 ++++ util/import_unicode.py | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f2e9356f..8ebb35067 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-17 Colin Watson + + * util/import_unicode.py: Remove unnecessary imports. + 2010-07-17 Aleš Nesrsta Hotplugging and USB hub support. diff --git a/util/import_unicode.py b/util/import_unicode.py index 1ee162d3f..8d17e7ef6 100644 --- a/util/import_unicode.py +++ b/util/import_unicode.py @@ -18,8 +18,6 @@ import re import sys -import os -import datetime if len (sys.argv) < 3: print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) From 139ab97dc3035212e28d7890f6ec0773ca5103ee Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 18 Jul 2010 15:53:14 +0100 Subject: [PATCH 440/503] * disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices, removing the homehost if present. * kern/emu/getroot.c (get_mdadm_name) [__linux__]: New function. (grub_util_get_grub_dev): Use md/%s to name mdadm 1.x devices, removing the homehost if present. (grub_util_get_grub_dev) [__linux__]: Get the array name from mdadm if possible. * util/i386/pc/grub-setup.c (main): Handle md/* devices. --- ChangeLog.raid | 11 +++++ disk/raid.c | 9 +++- kern/emu/getroot.c | 101 +++++++++++++++++++++++++++++++++++++- util/i386/pc/grub-setup.c | 4 +- 4 files changed, 120 insertions(+), 5 deletions(-) diff --git a/ChangeLog.raid b/ChangeLog.raid index 989f0bc09..c546a7632 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,14 @@ +2010-07-18 Colin Watson + + * disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices, + removing the homehost if present. + * kern/emu/getroot.c (get_mdadm_name) [__linux__]: New function. + (grub_util_get_grub_dev): Use md/%s to name mdadm 1.x devices, + removing the homehost if present. + (grub_util_get_grub_dev) [__linux__]: Get the array name from mdadm + if possible. + * util/i386/pc/grub-setup.c (main): Handle md/* devices. + 2009-12-15 Peter Henn * disk/mdraid_linux.c (grub_mdraid_detect): Fix calculation of 1.x diff --git a/disk/raid.c b/disk/raid.c index 87e713f30..1dc361e8e 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -563,7 +563,14 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, if (! array->name) array->name = grub_xasprintf ("md%d", array->number); else - array->name = grub_xasprintf ("%s", array->name); + { + /* Strip off the homehost if present. */ + char *colon = grub_strchr (array->name, ':'); + char *new_name = grub_xasprintf ("md/%s", + colon ? colon + 1 : array->name); + grub_free (array->name); + array->name = new_name; + } grub_dprintf ("raid", "Found array %s (%s)\n", array->name, scanner_name); diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 5b0849a98..2d7469c9d 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -36,6 +36,11 @@ #include #endif +#ifdef __linux__ +# include +# include +#endif + #include #include #include @@ -516,10 +521,89 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) return GRUB_DEV_ABSTRACTION_NONE; } +#ifdef __linux__ +static char * +get_mdadm_name (const char *os_dev) +{ + int mdadm_pipe[2]; + pid_t mdadm_pid; + char *name = NULL; + + if (pipe (mdadm_pipe) < 0) + { + grub_util_warn ("Unable to create pipe for mdadm: %s", strerror (errno)); + return NULL; + } + + mdadm_pid = fork (); + if (mdadm_pid < 0) + grub_util_warn ("Unable to fork mdadm: %s", strerror (errno)); + else if (mdadm_pid == 0) + { + /* Child. */ + char *argv[5]; + + close (mdadm_pipe[0]); + dup2 (mdadm_pipe[1], STDOUT_FILENO); + close (mdadm_pipe[1]); + + /* execvp has inconvenient types, hence the casts. None of these + strings will actually be modified. */ + argv[0] = (char *) "mdadm"; + argv[1] = (char *) "--detail"; + argv[2] = (char *) "--export"; + argv[3] = (char *) os_dev; + argv[4] = NULL; + execvp ("mdadm", argv); + exit (127); + } + else + { + /* Parent. Read mdadm's output. */ + FILE *mdadm; + char *buf = NULL; + size_t len = 0; + + close (mdadm_pipe[1]); + mdadm = fdopen (mdadm_pipe[0], "r"); + if (! mdadm) + { + grub_util_warn ("Unable to open stream from mdadm: %s", + strerror (errno)); + goto out; + } + + while (getline (&buf, &len, mdadm) > 0) + { + if (strncmp (buf, "MD_NAME=", sizeof ("MD_NAME=") - 1) == 0) + { + char *name_start, *colon; + size_t name_len; + + free (name); + name_start = buf + sizeof ("MD_NAME=") - 1; + /* Strip off the homehost if present. */ + colon = strchr (name_start, ':'); + name = strdup (colon ? colon + 1 : name_start); + name_len = strlen (name); + if (name[name_len - 1] == '\n') + name[name_len - 1] = '\0'; + } + } + +out: + close (mdadm_pipe[0]); + waitpid (mdadm_pid, NULL, 0); + } + + return name; +} +#endif /* __linux__ */ + char * grub_util_get_grub_dev (const char *os_dev) { - char *grub_dev; + char *grub_dev = NULL; switch (grub_util_get_dev_abstraction (os_dev)) { @@ -611,12 +695,25 @@ grub_util_get_grub_dev (const char *os_dev) if (q) *q = ','; - asprintf (&grub_dev, "%s", p); + asprintf (&grub_dev, "md/%s", p); free (p); } else grub_util_error ("unknown kind of RAID device `%s'", os_dev); +#ifdef __linux__ + { + char *mdadm_name = get_mdadm_name (os_dev); + + if (mdadm_name) + { + free (grub_dev); + asprintf (&grub_dev, "md/%s", mdadm_name); + free (mdadm_name); + } + } +#endif /* __linux__ */ + break; default: /* GRUB_DEV_ABSTRACTION_NONE */ diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 8b2f52bb4..524572fad 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -812,14 +812,14 @@ main (int argc, char *argv[]) must_embed = 1; if (root_dev[0] == 'm' && root_dev[1] == 'd' - && root_dev[2] >= '0' && root_dev[2] <= '9') + && ((root_dev[2] >= '0' && root_dev[2] <= '9') || root_dev[2] == '/')) { /* 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') + && ((dest_dev[2] >= '0' && dest_dev[2] <= '9') || dest_dev[2] == '/')) { char **devicelist; int i; From 1c785436daacfd914f8066fdb639fc22bd17ddbe Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 18 Jul 2010 18:31:10 +0100 Subject: [PATCH 441/503] * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Add start_sector parameter. Set its pointer target to 0. * disk/mdraid_linux.c (grub_mdraid_detect): Add start_sector parameter. Set its pointer target to 0 for 0.9 metadata, or to the `data_offset' value from the superblock for 1.x metadata. * disk/raid.c (grub_raid_read): Offset reads by the start sector of data on the device. (insert_array): Record the start sector of data on the device. (grub_raid_register): Pass start_sector parameters to grub_raid_list->detect and insert_array. * include/grub/raid.h (struct grub_raid_array): Add start_sector member. (struct grub_raid): Add start_sector parameter to `detect'. --- ChangeLog.raid | 16 ++++++++++++++++ disk/dmraid_nvidia.c | 5 ++++- disk/mdraid_linux.c | 7 ++++++- disk/raid.c | 15 ++++++++++----- include/grub/raid.h | 5 ++++- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/ChangeLog.raid b/ChangeLog.raid index c546a7632..a66bd6905 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,19 @@ +2010-07-18 Colin Watson + + * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Add start_sector + parameter. Set its pointer target to 0. + * disk/mdraid_linux.c (grub_mdraid_detect): Add start_sector + parameter. Set its pointer target to 0 for 0.9 metadata, or to the + `data_offset' value from the superblock for 1.x metadata. + * disk/raid.c (grub_raid_read): Offset reads by the start sector of + data on the device. + (insert_array): Record the start sector of data on the device. + (grub_raid_register): Pass start_sector parameters to + grub_raid_list->detect and insert_array. + * include/grub/raid.h (struct grub_raid_array): Add start_sector + member. + (struct grub_raid): Add start_sector parameter to `detect'. + 2010-07-18 Colin Watson * disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices, diff --git a/disk/dmraid_nvidia.c b/disk/dmraid_nvidia.c index 3e4ae33be..d3f45935c 100644 --- a/disk/dmraid_nvidia.c +++ b/disk/dmraid_nvidia.c @@ -89,7 +89,8 @@ struct grub_nv_super } __attribute__ ((packed)); static grub_err_t -grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) +grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array, + grub_disk_addr_t *start_sector) { grub_disk_addr_t sector; struct grub_nv_super sb; @@ -145,6 +146,8 @@ grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) grub_memcpy (array->uuid, (char *) &sb.array.signature, sizeof (sb.array.signature)); + *start_sector = 0; + return 0; } diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index 08e10ab45..b97e458ce 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -229,7 +229,8 @@ struct grub_raid_super_1x #define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ static grub_err_t -grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) +grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, + grub_disk_addr_t *start_sector) { grub_disk_addr_t sector; grub_uint64_t size, sb_size; @@ -328,6 +329,8 @@ superblock_0_90: uuid[2] = sb.set_uuid2; uuid[3] = sb.set_uuid3; + *start_sector = 0; + return 0; superblock_1_x: @@ -387,6 +390,8 @@ superblock_0_90: grub_memcpy (array->uuid, sb_1x->set_uuid, 16); + *start_sector = sb_1x->data_offset; + grub_free (sb_1x); return 0; } diff --git a/disk/raid.c b/disk/raid.c index 1dc361e8e..30d4b7ac4 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -254,7 +254,8 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, grub_errno = GRUB_ERR_NONE; err = grub_disk_read (array->device[k], - read_sector + j * far_ofs + b, + array->start_sector[k] + + read_sector + j * far_ofs + b, 0, read_size << GRUB_DISK_SECTOR_BITS, buf); @@ -366,7 +367,8 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, grub_errno = GRUB_ERR_NONE; err = grub_disk_read (array->device[disknr], - read_sector + b, 0, + array->start_sector[disknr] + + read_sector + b, 0, read_size << GRUB_DISK_SECTOR_BITS, buf); @@ -475,7 +477,7 @@ grub_raid_write (grub_disk_t disk __attribute ((unused)), static grub_err_t insert_array (grub_disk_t disk, struct grub_raid_array *new_array, - const char *scanner_name) + grub_disk_addr_t start_sector, const char *scanner_name) { struct grub_raid_array *array = 0, *p; @@ -524,6 +526,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, *array = *new_array; array->nr_devs = 0; grub_memset (&array->device, 0, sizeof (array->device)); + grub_memset (&array->start_sector, 0, sizeof (array->start_sector)); if (array->name) goto skip_duplicate_check; @@ -587,6 +590,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* Add the device to the array. */ array->device[new_array->index] = disk; + array->start_sector[new_array->index] = start_sector; array->nr_devs++; return 0; @@ -628,6 +632,7 @@ grub_raid_register (grub_raid_t raid) { grub_disk_t disk; struct grub_raid_array array; + grub_disk_addr_t start_sector; grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name); @@ -636,8 +641,8 @@ grub_raid_register (grub_raid_t raid) return 0; if ((disk->total_sectors != GRUB_ULONG_MAX) && - (! grub_raid_list->detect (disk, &array)) && - (! insert_array (disk, &array, grub_raid_list->name))) + (! grub_raid_list->detect (disk, &array, &start_sector)) && + (! insert_array (disk, &array, start_sector, grub_raid_list->name))) return 0; /* This error usually means it's not raid, no need to display diff --git a/include/grub/raid.h b/include/grub/raid.h index 8fa4c3814..00df9c10c 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -51,6 +51,8 @@ struct grub_raid_array 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. */ + grub_disk_addr_t start_sector[GRUB_RAID_MAX_DEVICES]; + /* Start of each device, in 512 byte sectors. */ struct grub_raid_array *next; }; @@ -58,7 +60,8 @@ struct grub_raid { const char *name; - grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array); + grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array, + grub_disk_addr_t *start_sector); struct grub_raid *next; }; From 68ac8c8d151cc3dc41c3e5ca578f6fea2a5941fe Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 19 Jul 2010 11:35:16 +0100 Subject: [PATCH 442/503] * disk/mdraid_linux.c (struct grub_raid_super_1x): Remove __attribute__ ((packed)), leaving a comment. (grub_mdraid_detect): Split out 0.9 and 1.x detection to ... (grub_mdraid_detect_09): ... here and ... (grub_mdraid_detect_1x): ... here. * disk/raid.c (insert_array): Check for grub_xasprintf returning NULL. --- ChangeLog.raid | 10 ++ disk/mdraid_linux.c | 261 +++++++++++++++++++++++--------------------- disk/raid.c | 20 +++- 3 files changed, 165 insertions(+), 126 deletions(-) diff --git a/ChangeLog.raid b/ChangeLog.raid index a66bd6905..d91f584c0 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,13 @@ +2010-07-19 Colin Watson + + * disk/mdraid_linux.c (struct grub_raid_super_1x): Remove + __attribute__ ((packed)), leaving a comment. + (grub_mdraid_detect): Split out 0.9 and 1.x detection to ... + (grub_mdraid_detect_09): ... here and ... + (grub_mdraid_detect_1x): ... here. + * disk/raid.c (insert_array): Check for grub_xasprintf returning + NULL. + 2010-07-18 Colin Watson * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Add start_sector diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index b97e458ce..b1199c6ef 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -224,31 +224,152 @@ struct grub_raid_super_1x * have a meaningful role. */ grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty. */ -} __attribute__ ((packed)); +}; +/* Could be __attribute__ ((packed)), but since all members in this struct + are already appropriately aligned, we can omit this and avoid suboptimal + assembly in some cases. */ #define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ +static grub_err_t +grub_mdraid_detect_09 (grub_disk_addr_t sector, + struct grub_raid_super_09 *sb, + struct grub_raid_array *array, + grub_disk_addr_t *start_sector) +{ + grub_uint32_t *uuid; + + 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->name = NULL; + 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; + + *start_sector = 0; + + return 0; +} + +static grub_err_t +grub_mdraid_detect_1x (grub_disk_t disk, grub_disk_addr_t sector, + struct grub_raid_super_1x *sb, + struct grub_raid_array *array, + grub_disk_addr_t *start_sector) +{ + grub_uint64_t sb_size; + struct grub_raid_super_1x *real_sb; + + if (sb->major_version != 1) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID version: %d", + sb->major_version); + + /* 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); + + /* 1.x superblocks don't have a fixed size on disk. So we have to + read it again now that we now the max device count. */ + sb_size = sizeof (struct grub_raid_super_1x) + 2 * grub_le_to_cpu32 (sb->max_dev); + real_sb = grub_malloc (sb_size); + if (! real_sb) + return grub_errno; + + if (grub_disk_read (disk, sector, 0, sb_size, real_sb)) + { + grub_free (real_sb); + return grub_errno; + } + + array->name = grub_strdup (real_sb->set_name); + if (! array->name) + { + grub_free (real_sb); + return grub_errno; + } + + array->number = 0; + array->level = grub_le_to_cpu32 (real_sb->level); + array->layout = grub_le_to_cpu32 (real_sb->layout); + array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks); + array->disk_size = grub_le_to_cpu64 (real_sb->size); + array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize); + if (grub_le_to_cpu32 (real_sb->dev_number) < + grub_le_to_cpu32 (real_sb->max_dev)) + array->index = grub_le_to_cpu16 + (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); + else + array->index = 0xffff; /* disk will be later not used! */ + array->uuid_len = 16; + array->uuid = grub_malloc (16); + if (!array->uuid) + { + grub_free (real_sb); + return grub_errno; + } + + grub_memcpy (array->uuid, real_sb->set_uuid, 16); + + *start_sector = real_sb->data_offset; + + grub_free (real_sb); + return 0; +} + static grub_err_t grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, grub_disk_addr_t *start_sector) { grub_disk_addr_t sector; - grub_uint64_t size, sb_size; - struct grub_raid_super_09 sb; - struct grub_raid_super_1x *sb_1x; - grub_uint32_t *uuid; + grub_uint64_t size; + struct grub_raid_super_09 sb_09; + struct grub_raid_super_1x sb_1x; grub_uint8_t minor_version; /* The sector where the mdraid 0.90 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, &sb)) + if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb_09)) return grub_errno; /* Look whether there is a mdraid 0.90 superblock. */ - if (sb.md_magic == SB_MAGIC) - goto superblock_0_90; + if (sb_09.md_magic == SB_MAGIC) + return grub_mdraid_detect_09 (sector, &sb_09, array, start_sector); /* Check for an 1.x superblock. * It's always aligned to a 4K boundary @@ -258,10 +379,6 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, * 2: 4K from start of device. */ - sb_1x = grub_malloc (sizeof (struct grub_raid_super_1x)); - if (!sb_1x) - return grub_errno; - for (minor_version = 0; minor_version < 3; ++minor_version) { switch (minor_version) @@ -277,123 +394,17 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, break; } - if (grub_disk_read - (disk, sector, 0, sizeof (struct grub_raid_super_1x), sb_1x)) - { - grub_free (sb_1x); - return grub_errno; - } + if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1x), + &sb_1x)) + return grub_errno; - if (sb_1x->magic == SB_MAGIC) - goto superblock_1_x; + if (sb_1x.magic == SB_MAGIC) + return grub_mdraid_detect_1x (disk, sector, &sb_1x, array, + start_sector); } /* Neither 0.90 nor 1.x. */ - if (grub_le_to_cpu32 (sb_1x->magic) != SB_MAGIC) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); - -superblock_0_90: - - 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->name = NULL; - 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; - - *start_sector = 0; - - return 0; - - superblock_1_x: - - if (sb_1x->major_version != 1) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID version: %d", - sb_1x->major_version); - /* Multipath. */ - if ((int) sb_1x->level == -4) - sb_1x->level = 1; - - if (sb_1x->level != 0 && sb_1x->level != 1 && sb_1x->level != 4 && - sb_1x->level != 5 && sb_1x->level != 6 && sb_1x->level != 10) - { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID level: %d", sb_1x->level); - grub_free (sb_1x); - } - /* 1.x superblocks don't have a fixed size on disk. So we have to - read it again now that we now the max device count. */ - sb_size = sizeof (struct grub_raid_super_1x) + 2 * grub_le_to_cpu32 (sb_1x->max_dev); - sb_1x = grub_realloc (sb_1x, sb_size); - if (! sb_1x) - return grub_errno; - - if (grub_disk_read (disk, sector, 0, sb_size, sb_1x)) - { - grub_free (sb_1x); - return grub_errno; - } - - array->name = grub_strdup (sb_1x->set_name); - if (! array->name) - { - grub_free (sb_1x); - return grub_errno; - } - - array->number = 0; - array->level = grub_le_to_cpu32 (sb_1x->level); - array->layout = grub_le_to_cpu32 (sb_1x->layout); - array->total_devs = grub_le_to_cpu32 (sb_1x->raid_disks); - array->disk_size = grub_le_to_cpu64 (sb_1x->size); - array->chunk_size = grub_le_to_cpu32 (sb_1x->chunksize); - if (grub_le_to_cpu32 (sb_1x->dev_number) < grub_le_to_cpu32 (sb_1x->max_dev)) - array->index = grub_le_to_cpu16 (sb_1x->dev_roles[grub_le_to_cpu32 (sb_1x->dev_number)]); - else - array->index = 0xffff; /* disk will be later not used! */ - array->uuid_len = 16; - array->uuid = grub_malloc (16); - if (!array->uuid) - { - grub_free (sb_1x); - return grub_errno; - } - - grub_memcpy (array->uuid, sb_1x->set_uuid, 16); - - *start_sector = sb_1x->data_offset; - - grub_free (sb_1x); - return 0; + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); } static struct grub_raid grub_mdraid_dev = { diff --git a/disk/raid.c b/disk/raid.c index 30d4b7ac4..2f70e256f 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -564,13 +564,31 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* mdraid 1.x superblocks have only a name stored not a number. Use it directly as GRUB device. */ if (! array->name) - array->name = grub_xasprintf ("md%d", array->number); + { + array->name = grub_xasprintf ("md%d", array->number); + if (! array->name) + { + grub_free (array->uuid); + grub_free (array); + + return grub_errno; + } + } else { /* Strip off the homehost if present. */ char *colon = grub_strchr (array->name, ':'); char *new_name = grub_xasprintf ("md/%s", colon ? colon + 1 : array->name); + + if (! new_name) + { + grub_free (array->uuid); + grub_free (array); + + return grub_errno; + } + grub_free (array->name); array->name = new_name; } From 31cfe714f21c325f9acf3e3213f7a1361e8b5bfd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 20 Jul 2010 11:10:49 +0100 Subject: [PATCH 443/503] * disk/mdraid_linux.c: Update copyright years. * disk/raid.c: Likewise. * include/grub/raid.h: Likewise. * kern/emu/getroot.c: Likewise. --- ChangeLog.raid | 7 +++++++ disk/mdraid_linux.c | 2 +- disk/raid.c | 2 +- include/grub/raid.h | 2 +- kern/emu/getroot.c | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog.raid b/ChangeLog.raid index d91f584c0..10215f7fd 100644 --- a/ChangeLog.raid +++ b/ChangeLog.raid @@ -1,3 +1,10 @@ +2010-07-20 Colin Watson + + * disk/mdraid_linux.c: Update copyright years. + * disk/raid.c: Likewise. + * include/grub/raid.h: Likewise. + * kern/emu/getroot.c: Likewise. + 2010-07-19 Colin Watson * disk/mdraid_linux.c (struct grub_raid_super_1x): Remove diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index b1199c6ef..d5a0aad47 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -1,7 +1,7 @@ /* mdraid_linux.c - module to handle Linux Software RAID. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/disk/raid.c b/disk/raid.c index 2f70e256f..43d2a29ff 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -1,7 +1,7 @@ /* raid.c - module to read RAID arrays. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/grub/raid.h b/include/grub/raid.h index 00df9c10c..711a7f79c 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -1,7 +1,7 @@ /* raid.h - On disk structures for RAID. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,2008,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 2d7469c9d..9f89bf657 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -1,7 +1,7 @@ /* getroot.c - Get root device */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 4b761da90280153c13ff850c9e0e1b19daf719b1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 20 Jul 2010 11:20:23 +0100 Subject: [PATCH 444/503] * .bzrignore: Ignore 20_linux_xen. --- .bzrignore | 1 + ChangeLog | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.bzrignore b/.bzrignore index daf9da53a..32b96b154 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1,5 +1,6 @@ 00_header 10_* +20_linux_xen 30_os-prober 40_custom 41_custom diff --git a/ChangeLog b/ChangeLog index 8ebb35067..200058f29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-20 Colin Watson + + * .bzrignore: Ignore 20_linux_xen. + 2010-07-17 Colin Watson * util/import_unicode.py: Remove unnecessary imports. From 39d824e8f9379e957b3389c63419ffa787a80aa1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 20 Jul 2010 14:42:32 +0200 Subject: [PATCH 445/503] * commands/acpi.c (setup_common_tables): Use sizeof instead of hardcoding size. (setv1table): Likewise. --- ChangeLog | 6 ++++++ commands/acpi.c | 14 ++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index fab3ecb22..66d810e91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-20 Vladimir Serbinenko + + * commands/acpi.c (setup_common_tables): Use sizeof instead of + hardcoding size. + (setv1table): Likewise. + 2010-07-20 Colin Watson * disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices, diff --git a/commands/acpi.c b/commands/acpi.c index 5bbfd008b..884ddf000 100644 --- a/commands/acpi.c +++ b/commands/acpi.c @@ -325,7 +325,8 @@ setup_common_tables (void) /* If it's FADT correct DSDT and FACS addresses. */ fadt = (struct grub_acpi_fadt *) cur->addr; - if (grub_memcmp (fadt->hdr.signature, "FACP", 4) == 0) + if (grub_memcmp (fadt->hdr.signature, "FACP", + sizeof (fadt->hdr.signature)) == 0) { fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt); fadt->facs_addr = facs_addr; @@ -351,16 +352,16 @@ setup_common_tables (void) rsdt_addr = rsdt = (struct grub_acpi_table_header *) playground_ptr; playground_ptr += sizeof (struct grub_acpi_table_header) + 4 * numoftables; - rsdt_entry = (grub_uint32_t *)(rsdt + 1); + rsdt_entry = (grub_uint32_t *) (rsdt + 1); /* Fill RSDT header. */ grub_memcpy (&(rsdt->signature), "RSDT", 4); rsdt->length = sizeof (struct grub_acpi_table_header) + 4 * numoftables; rsdt->revision = 1; - grub_memcpy (&(rsdt->oemid), root_oemid, 6); - grub_memcpy (&(rsdt->oemtable), root_oemtable, 4); + grub_memcpy (&(rsdt->oemid), root_oemid, sizeof (rsdt->oemid)); + grub_memcpy (&(rsdt->oemtable), root_oemtable, sizeof (rsdt->oemtable)); rsdt->oemrev = root_oemrev; - grub_memcpy (&(rsdt->creator_id), root_creator_id, 6); + grub_memcpy (&(rsdt->creator_id), root_creator_id, sizeof (rsdt->creator_id)); rsdt->creator_rev = root_creator_rev; for (cur = acpi_tables; cur; cur = cur->next) @@ -378,7 +379,8 @@ setv1table (void) /* Create RSDP. */ rsdpv1_new = (struct grub_acpi_rsdp_v10 *) playground_ptr; playground_ptr += sizeof (struct grub_acpi_rsdp_v10); - grub_memcpy (&(rsdpv1_new->signature), "RSD PTR ", 8); + grub_memcpy (&(rsdpv1_new->signature), "RSD PTR ", + sizeof (rsdpv1_new->signature)); grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof (rsdpv1_new->oemid)); rsdpv1_new->revision = 0; rsdpv1_new->rsdt_addr = PTR_TO_UINT32 (rsdt_addr); From a29d6a4bc516c1f7cb0f142714ad4b85e9b3a1b2 Mon Sep 17 00:00:00 2001 From: Thomas Frauendorfer Date: Tue, 20 Jul 2010 15:59:56 +0200 Subject: [PATCH 446/503] * lib/i386/relocator_asm.S [! __x86_64__]: Don't try to disable amd64 on i386. --- ChangeLog | 5 +++++ lib/i386/relocator_asm.S | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 66d810e91..d5e655b90 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-20 Thomas Frauendorfer + + * lib/i386/relocator_asm.S [! __x86_64__]: Don't try to disable amd64 + on i386. + 2010-07-20 Vladimir Serbinenko * commands/acpi.c (setup_common_tables): Use sizeof instead of diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index 6b803db13..22490a3f8 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -157,11 +157,13 @@ LOCAL(cont1): andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax movl %eax, %cr0 +#ifdef __x86_64__ /* Disable amd64. */ movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx rdmsr andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax wrmsr +#endif /* Turn off PAE. */ movl %cr4, %eax From ab8ba957608a44a6f6ccf3a9f6055dd71f853f78 Mon Sep 17 00:00:00 2001 From: Vadim Solomin Date: Tue, 20 Jul 2010 17:14:00 +0100 Subject: [PATCH 447/503] 2010-07-20 Vadim Solomin 2010-07-20 Colin Watson Generate device.map in something closer to the old ordering. * util/deviceiter.c (struct device): New declaration. (compare_file_names): Rename to ... (compare_devices): ... this. Sort by kernel name in preference to the stable by-id name, but keep the latter as a fallback comparison. Update header comment. (grub_util_iterate_devices) [__linux__]: Construct and sort an array of `struct device' rather than of plain file names. Also-By: Colin Watson --- ChangeLog | 13 ++++++++++ util/deviceiter.c | 66 +++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5e655b90..aa4d0b530 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-07-20 Vadim Solomin +2010-07-20 Colin Watson + + Generate device.map in something closer to the old ordering. + + * util/deviceiter.c (struct device): New declaration. + (compare_file_names): Rename to ... + (compare_devices): ... this. Sort by kernel name in preference to + the stable by-id name, but keep the latter as a fallback comparison. + Update header comment. + (grub_util_iterate_devices) [__linux__]: Construct and sort an array + of `struct device' rather than of plain file names. + 2010-07-20 Thomas Frauendorfer * lib/i386/relocator_asm.S [! __x86_64__]: Don't try to disable amd64 diff --git a/util/deviceiter.c b/util/deviceiter.c index bbcc00a91..1cf511934 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -467,13 +467,30 @@ clear_seen_devices (void) } #ifdef __linux__ -/* Like strcmp, but doesn't require a cast for use as a qsort comparator. */ -static int -compare_file_names (const void *a, const void *b) +struct device { - const char *left = *(const char **) a; - const char *right = *(const char **) b; - return strcmp (left, right); + char *stable; + char *kernel; +}; + +/* Sort by the kernel name for preference since that most closely matches + older device.map files, but sort by stable by-id names as a fallback. + This is because /dev/disk/by-id/ usually has a few alternative + identifications of devices (e.g. ATA vs. SATA). + check_device_readable_unique will ensure that we only get one for any + given disk, but sort the list so that the choice of which one we get is + stable. */ +static int +compare_devices (const void *a, const void *b) +{ + const struct device *left = (const struct device *) a; + const struct device *right = (const struct device *) b; + int ret; + ret = strcmp (left->kernel, right->kernel); + if (ret) + return ret; + else + return strcmp (left->stable, right->stable); } #endif /* __linux__ */ @@ -507,10 +524,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), if (dir) { struct dirent *entry; - char **names; - size_t names_len = 0, names_max = 1024, i; + struct device *devs; + size_t devs_len = 0, devs_max = 1024, i; - names = xmalloc (names_max * sizeof (*names)); + devs = xmalloc (devs_max * sizeof (*devs)); /* Dump all the directory entries into names, resizing if necessary. */ @@ -526,35 +543,34 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), /* Skip RAID entries; they are handled by upper layers. */ if (strncmp (entry->d_name, "md-", sizeof ("md-") - 1) == 0) continue; - if (names_len >= names_max) + if (devs_len >= devs_max) { - names_max *= 2; - names = xrealloc (names, names_max * sizeof (*names)); + devs_max *= 2; + devs = xrealloc (devs, devs_max * sizeof (*devs)); } - names[names_len++] = xasprintf (entry->d_name); + devs[devs_len].stable = + xasprintf ("/dev/disk/by-id/%s", entry->d_name); + devs[devs_len].kernel = + canonicalize_file_name (devs[devs_len].stable); + devs_len++; } - /* /dev/disk/by-id/ usually has a few alternative identifications of - devices (e.g. ATA vs. SATA). check_device_readable_unique will - ensure that we only get one for any given disk, but sort the list - so that the choice of which one we get is stable. */ - qsort (names, names_len, sizeof (*names), &compare_file_names); + qsort (devs, devs_len, sizeof (*devs), &compare_devices); closedir (dir); /* Now add all the devices in sorted order. */ - for (i = 0; i < names_len; ++i) + for (i = 0; i < devs_len; ++i) { - char *path = xasprintf ("/dev/disk/by-id/%s", names[i]); - if (check_device_readable_unique (path)) + if (check_device_readable_unique (devs[i].stable)) { - if (hook (path, 0)) + if (hook (devs[i].stable, 0)) goto out; } - free (path); - free (names[i]); + free (devs[i].stable); + free (devs[i].kernel); } - free (names); + free (devs); } } From 64a638b0d9d428a757c2d067131d2fbf1e88b2ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 20 Jul 2010 20:22:52 +0200 Subject: [PATCH 448/503] * docs/grub.texi (Naming convention): Document new naming convention. --- ChangeLog | 4 ++++ docs/grub.texi | 22 ++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa4d0b530..8fccf3490 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-20 Vladimir Serbinenko + + * docs/grub.texi (Naming convention): Document new naming convention. + 2010-07-20 Vadim Solomin 2010-07-20 Colin Watson diff --git a/docs/grub.texi b/docs/grub.texi index 5d412ecd4..a191ef9ef 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -444,12 +444,13 @@ disk. The number @samp{0} is the drive number, which is counted from disk. @example -(hd0,2) +(hd0,msdos2) @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 +@samp{0} indicates the drive number, that is, the first hard disk, +the string @samp{msdos} indicates the partition scheme, while +the second integer, @samp{2}, indicates the partition number (or the @sc{pc} slice number in the BSD terminology). The partition numbers are counted from @emph{one}, not from zero (as was the case in previous versions of GRUB). This expression means the second partition of the @@ -457,7 +458,7 @@ first hard disk drive. In this case, GRUB uses one partition of the disk, instead of the whole disk. @example -(hd0,5) +(hd0,msdos5) @end example This specifies the first @dfn{extended partition} of the first hard disk @@ -466,18 +467,15 @@ counted from @samp{5}, regardless of the actual number of primary partitions on your hard disk. @example -(hd1,a) +(hd1,msdos1,bsd1) @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,1,a)}. If the @sc{pc} slice number is omitted, -GRUB searches for the first @sc{pc} slice which has a BSD @samp{a} -partition. +This means the BSD @samp{a} partition on first @sc{pc} slice number +of the second hard disk. Of course, to actually access the disks or partitions with GRUB, you need to use the device specification in a command, like @samp{set -root=(fd0)} or @samp{parttool (hd0,3) hidden-}. To help you find out +root=(fd0)} or @samp{parttool (hd0,msdos3) hidden-}. 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 @@ -501,7 +499,7 @@ Now the question is, how to specify a file? Again, consider an example: @example -(hd0,1)/vmlinuz +(hd0,msdos1)/vmlinuz @end example This specifies the file named @samp{vmlinuz}, found on the first From a6a11f3cac8703b662c7a8424fea21a1e2c3ffd0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 20 Jul 2010 20:36:11 +0200 Subject: [PATCH 449/503] * util/i386/efi/grub-install.in: Revert to platform-specific behaviour with -p "". Reported by: Tito Keitel. --- ChangeLog | 6 ++++++ util/i386/efi/grub-install.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8fccf3490..2e6853371 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-20 Vladimir Serbinenko + + * util/i386/efi/grub-install.in: Revert to platform-specific behaviour + with -p "". + Reported by: Tito Keitel. + 2010-07-20 Vladimir Serbinenko * docs/grub.texi (Naming convention): Document new naming convention. diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index 269317cd0..d8554a328 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -246,7 +246,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma # The order in this list is critical. Be careful when modifying it. modules="$modules $fs_module $partmap_module $devabstraction_module" -$grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 1 +$grub_mkimage -p "" -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 1 # Prompt the user to check if the device map is correct. echo "Installation finished. No error reported." From afaec079d13d3c71976c449d7f1cc7f1c3a65a6a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 20 Jul 2010 21:56:00 +0200 Subject: [PATCH 450/503] * disk/loopback.c (grub_loopback): Replace filename with file. (delete_loopback): Handle new semantics. (grub_cmd_loopback): Likewise. (grub_loopback_iterate): Likewise. (grub_loopback_close): Likewise. --- ChangeLog | 8 ++++++++ disk/loopback.c | 33 ++++++++------------------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e6853371..2fc4a9793 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-07-20 Vladimir Serbinenko + + * disk/loopback.c (grub_loopback): Replace filename with file. + (delete_loopback): Handle new semantics. + (grub_cmd_loopback): Likewise. + (grub_loopback_iterate): Likewise. + (grub_loopback_close): Likewise. + 2010-07-20 Vladimir Serbinenko * util/i386/efi/grub-install.in: Revert to platform-specific behaviour diff --git a/disk/loopback.c b/disk/loopback.c index 1b525e05f..4990da710 100644 --- a/disk/loopback.c +++ b/disk/loopback.c @@ -28,7 +28,7 @@ struct grub_loopback { char *devname; - char *filename; + grub_file_t file; int has_partitions; struct grub_loopback *next; }; @@ -63,7 +63,7 @@ delete_loopback (const char *name) *prev = dev->next; grub_free (dev->devname); - grub_free (dev->filename); + grub_file_close (dev->file); grub_free (dev); return 0; @@ -91,9 +91,6 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) 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) @@ -105,8 +102,8 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) if (! newname) return grub_errno; - grub_free (newdev->filename); - newdev->filename = newname; + grub_file_close (newdev->file); + newdev->file = file; /* Set has_partitions when `--partitions' was used. */ newdev->has_partitions = state[1].set; @@ -126,13 +123,7 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) return grub_errno; } - newdev->filename = grub_strdup (args[1]); - if (! newdev->filename) - { - grub_free (newdev->devname); - grub_free (newdev); - return grub_errno; - } + newdev->file = file; /* Set has_partitions when `--partitions' was used. */ newdev->has_partitions = state[1].set; @@ -160,7 +151,6 @@ grub_loopback_iterate (int (*hook) (const char *name)) 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) @@ -170,27 +160,20 @@ grub_loopback_open (const char *name, grub_disk_t disk) 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) + disk->total_sectors = ((dev->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; + disk->data = dev->file; return 0; } static void -grub_loopback_close (grub_disk_t disk) +grub_loopback_close (grub_disk_t disk __attribute__ ((unused))) { - grub_file_t file = (grub_file_t) disk->data; - - grub_file_close (file); } static grub_err_t From 5e3bec6716529da996700270d51bca17232da01c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 20 Jul 2010 22:10:23 +0200 Subject: [PATCH 451/503] * tests/util/grub-shell-tester.in: Remove bashism and declare as sh script. --- ChangeLog | 5 +++++ tests/util/grub-shell-tester.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2fc4a9793..5e3b7ff04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-07-20 Vladimir Serbinenko + + * tests/util/grub-shell-tester.in: Remove bashism and declare as + sh script. + 2010-07-20 Vladimir Serbinenko * disk/loopback.c (grub_loopback): Replace filename with file. diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in index e9507c8f5..ed34a5e17 100644 --- a/tests/util/grub-shell-tester.in +++ b/tests/util/grub-shell-tester.in @@ -1,4 +1,4 @@ -#! /bin/bash -e +#! /bin/sh -e # Compares GRUB script output with BASH output. # Copyright (C) 2009,2010 Free Software Foundation, Inc. @@ -84,7 +84,7 @@ done if [ "x${source}" = x ] ; then tmpfile=`mktemp` - while read; do + while read REPLY; do echo $REPLY >> ${tmpfile} done source=${tmpfile} From dd8ff5c9e9aae0cbfe27b6195ba3a256ba454351 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 20 Jul 2010 22:00:18 +0100 Subject: [PATCH 452/503] Disable EFI cursor when the EFI console becomes inactive. * term/efi/console.c (grub_efi_console_init): New function. (grub_efi_console_fini): New function. (grub_console_term_output): Register init and fini methods. --- ChangeLog | 8 ++++++++ term/efi/console.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5e3b7ff04..681b6fd24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-07-20 Colin Watson + + Disable EFI cursor when the EFI console becomes inactive. + + * term/efi/console.c (grub_efi_console_init): New function. + (grub_efi_console_fini): New function. + (grub_console_term_output): Register init and fini methods. + 2010-07-20 Vladimir Serbinenko * tests/util/grub-shell-tester.in: Remove bashism and declare as diff --git a/term/efi/console.c b/term/efi/console.c index d3240590b..dca002910 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -311,6 +311,20 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), efi_call_2 (o->enable_cursor, o, on); } +static grub_err_t +grub_efi_console_init (struct grub_term_output *term) +{ + grub_console_setcursor (term, 1); + return 0; +} + +static grub_err_t +grub_efi_console_fini (struct grub_term_output *term) +{ + grub_console_setcursor (term, 0); + return 0; +} + static struct grub_term_input grub_console_term_input = { .name = "console", @@ -321,6 +335,8 @@ static struct grub_term_input grub_console_term_input = static struct grub_term_output grub_console_term_output = { .name = "console", + .init = grub_efi_console_init, + .fini = grub_efi_console_fini, .putchar = grub_console_putchar, .getwh = grub_console_getwh, .getxy = grub_console_getxy, From efc9d7f175cd1750d286be0aeec8414084394226 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 20 Jul 2010 22:14:26 +0100 Subject: [PATCH 453/503] * disk/loopback.c (grub_cmd_loopback): Don't leak a grub_file_t handle on failure. (grub_loopback_close): Remove empty function. (grub_loopback_dev): Remove close method. --- ChangeLog | 7 +++++++ disk/loopback.c | 18 +++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 681b6fd24..482874788 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-07-20 Colin Watson + + * disk/loopback.c (grub_cmd_loopback): Don't leak a grub_file_t + handle on failure. + (grub_loopback_close): Remove empty function. + (grub_loopback_dev): Remove close method. + 2010-07-20 Colin Watson Disable EFI cursor when the EFI console becomes inactive. diff --git a/disk/loopback.c b/disk/loopback.c index 4990da710..509e9e33f 100644 --- a/disk/loopback.c +++ b/disk/loopback.c @@ -76,6 +76,7 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) struct grub_arg_list *state = state = cmd->state; grub_file_t file; struct grub_loopback *newdev; + grub_err_t ret; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); @@ -100,7 +101,7 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) { char *newname = grub_strdup (args[1]); if (! newname) - return grub_errno; + goto fail; grub_file_close (newdev->file); newdev->file = file; @@ -114,13 +115,13 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) /* Unable to replace it, make a new entry. */ newdev = grub_malloc (sizeof (struct grub_loopback)); if (! newdev) - return grub_errno; + goto fail; newdev->devname = grub_strdup (args[0]); if (! newdev->devname) { grub_free (newdev); - return grub_errno; + goto fail; } newdev->file = file; @@ -133,6 +134,11 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) loopback_list = newdev; return 0; + +fail: + ret = grub_errno; + grub_file_close (file); + return ret; } @@ -171,11 +177,6 @@ grub_loopback_open (const char *name, grub_disk_t disk) return 0; } -static void -grub_loopback_close (grub_disk_t disk __attribute__ ((unused))) -{ -} - static grub_err_t grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) @@ -217,7 +218,6 @@ static struct grub_disk_dev grub_loopback_dev = .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 From b26f1c116062715690eb91dc301cdbd844d8f793 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 20 Jul 2010 23:09:45 +0100 Subject: [PATCH 454/503] * kern/emu/getroot.c (grub_util_get_grub_dev): Use xasprintf. --- ChangeLog | 4 ++++ kern/emu/getroot.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 482874788..0d06dee3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-20 Colin Watson + + * kern/emu/getroot.c (grub_util_get_grub_dev): Use xasprintf. + 2010-07-20 Colin Watson * disk/loopback.c (grub_cmd_loopback): Don't leak a grub_file_t diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 9f89bf657..58dbac9b4 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -695,7 +695,7 @@ grub_util_get_grub_dev (const char *os_dev) if (q) *q = ','; - asprintf (&grub_dev, "md/%s", p); + grub_dev = xasprintf ("md/%s", p); free (p); } else @@ -708,7 +708,7 @@ grub_util_get_grub_dev (const char *os_dev) if (mdadm_name) { free (grub_dev); - asprintf (&grub_dev, "md/%s", mdadm_name); + grub_dev = xasprintf ("md/%s", mdadm_name); free (mdadm_name); } } From c03507dfb87adb5ab6e5eb619ab9dd9d3d30642c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 20 Jul 2010 23:16:32 +0100 Subject: [PATCH 455/503] * bus/usb/emu/usb.c (grub_usb_poll_devices): Add a dummy implementation of this so that grub-emu links again, with a note that this should support hotplugging in the future. --- ChangeLog | 6 ++++++ bus/usb/emu/usb.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0d06dee3b..c05891b96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-20 Colin Watson + + * bus/usb/emu/usb.c (grub_usb_poll_devices): Add a dummy + implementation of this so that grub-emu links again, with a note + that this should support hotplugging in the future. + 2010-07-20 Colin Watson * kern/emu/getroot.c (grub_util_get_grub_dev): Use xasprintf. diff --git a/bus/usb/emu/usb.c b/bus/usb/emu/usb.c index 187857b5b..7d52decb2 100644 --- a/bus/usb/emu/usb.c +++ b/bus/usb/emu/usb.c @@ -78,6 +78,12 @@ grub_libusb_devices (void) return GRUB_USB_ERR_NONE; } +void +grub_usb_poll_devices (void) +{ + /* TODO: recheck grub_usb_devs */ +} + int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) From a9600892c190269c25613fede79892a17f0490e0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 22 Jul 2010 09:38:06 +0100 Subject: [PATCH 456/503] * disk/raid.c (insert_array): Don't count named arrays when looking for unused array numbers. Reported and tested by: maru. --- ChangeLog | 6 ++++++ disk/raid.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c05891b96..e3677b0e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-22 Colin Watson + + * disk/raid.c (insert_array): Don't count named arrays when looking + for unused array numbers. + Reported and tested by: maru. + 2010-07-20 Colin Watson * bus/usb/emu/usb.c (grub_usb_poll_devices): Add a dummy diff --git a/disk/raid.c b/disk/raid.c index 43d2a29ff..7dfd4bd81 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -533,7 +533,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* 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) + if (! p->name && p->number == array->number) break; } @@ -546,7 +546,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, { for (p = array_list; p != NULL; p = p->next) { - if (p->number == i) + if (! p->name && p->number == i) break; } From 697e053c44e75734ad4ae7520e63a80a83df4059 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 22 Jul 2010 09:44:19 +0100 Subject: [PATCH 457/503] real name for Michael Guntsche --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e3677b0e2..e0c2096bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ * disk/raid.c (insert_array): Don't count named arrays when looking for unused array numbers. - Reported and tested by: maru. + Reported and tested by: Michael Guntsche. 2010-07-20 Colin Watson From 0ac33bf5eb13bd185c903ac29a3ec36f0502c74f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 21 Jul 2010 06:44:38 +0200 Subject: [PATCH 458/503] * util/grub.d/00_header.in: Remove compatibility with terminal.mod prior to terminal_input/terminal_output separation. It's been over 1.5 years and those versions weren't widely deployed. --- ChangeLog | 6 ++++++ util/grub.d/00_header.in | 12 ++---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0c2096bb..de1edebb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,12 @@ (grub_efi_console_fini): New function. (grub_console_term_output): Register init and fini methods. +2010-07-20 Vladimir Serbinenko + + * util/grub.d/00_header.in: Remove compatibility with terminal.mod + prior to terminal_input/terminal_output separation. It's been over 1.5 + years and those versions weren't widely deployed. + 2010-07-20 Vladimir Serbinenko * tests/util/grub-shell-tester.in: Remove bashism and declare as diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 75c8b0fa2..2f39650e9 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -137,11 +137,7 @@ case x${GRUB_TERMINAL_INPUT} in ;; 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 +terminal_input ${GRUB_TERMINAL_INPUT} EOF ;; esac @@ -152,11 +148,7 @@ case x${GRUB_TERMINAL_OUTPUT} in ;; 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 +terminal_output ${GRUB_TERMINAL_OUTPUT} EOF ;; esac From f2bf127859506b888cd81ed52f684a5b9a69a78c Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 23 Jul 2010 04:05:15 +0530 Subject: [PATCH 459/503] add comment --- script/argv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/script/argv.c b/script/argv.c index 69322779d..b69ee39c5 100644 --- a/script/argv.c +++ b/script/argv.c @@ -20,6 +20,7 @@ #include #include +/* Return nearest power of two that is >= v. */ static unsigned round_up_exp (unsigned v) { From 463711215f2420d12fad9b45d9a02b8a01668651 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 28 Jul 2010 18:25:48 +0300 Subject: [PATCH 460/503] * util/ieee1275/grub-install.in: Don't use empty grub_device. Reported by: Lennart Sorensen. --- ChangeLog | 17 +++++++++++------ util/ieee1275/grub-install.in | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index de1edebb1..a2b6a2bc1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-07-28 Vladimir Serbinenko + + * util/ieee1275/grub-install.in: Don't use empty grub_device. + Reported by: Lennart Sorensen. + +2010-07-20 Vladimir Serbinenko + + * util/grub.d/00_header.in: Remove compatibility with terminal.mod + prior to terminal_input/terminal_output separation. It's been over 1.5 + years and those versions weren't widely deployed. + 2010-07-22 Colin Watson * disk/raid.c (insert_array): Don't count named arrays when looking @@ -29,12 +40,6 @@ (grub_efi_console_fini): New function. (grub_console_term_output): Register init and fini methods. -2010-07-20 Vladimir Serbinenko - - * util/grub.d/00_header.in: Remove compatibility with terminal.mod - prior to terminal_input/terminal_output separation. It's been over 1.5 - years and those versions weren't widely deployed. - 2010-07-20 Vladimir Serbinenko * tests/util/grub-shell-tester.in: Remove bashism and declare as diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 98fd5d65a..98de5f348 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -212,7 +212,7 @@ fi # this command is allowed to fail (--target=fs already grants us that the # filesystem will be accessible). partmap_module= -for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do +for x in `$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`; do partmap_module="$partmap_module part_$x"; done From 9f841f5cbfcdf52cb7a5e0f51e5239466f6fd67f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 29 Jul 2010 15:06:39 +0200 Subject: [PATCH 461/503] 2010-07-29 Robert Millan * configure.ac: Remove grub-mkisofs checks. --- ChangeLog | 4 ++++ configure.ac | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2b6a2bc1..af48d4039 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-29 Robert Millan + + * configure.ac: Remove grub-mkisofs checks. + 2010-07-28 Vladimir Serbinenko * util/ieee1275/grub-install.in: Don't use empty grub_device. diff --git a/configure.ac b/configure.ac index 55c2625cb..aa7f3a151 100644 --- a/configure.ac +++ b/configure.ac @@ -249,13 +249,6 @@ fi # Check for functions. AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf) -# For grub-mkisofs -AC_HEADER_MAJOR -AC_HEADER_DIRENT -AC_CHECK_FUNCS(memmove sbrk strdup lstat getuid getgid) -AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h) -AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h limits.h) - # For opendisk() and getrawpartition() on NetBSD. # Used in util/deviceiter.c and in util/hostdisk.c. AC_CHECK_HEADER([util.h], [ From 0806b63c0964c456e667415a1d8d3fa8521ac14b Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 29 Jul 2010 18:46:42 +0200 Subject: [PATCH 462/503] 2010-07-29 Robert Millan * util/grub-probe.c (PRINT_FS_LABEL): New enum value. (probe): Handle `PRINT_FS_LABEL'. (main): Handle `-t fs_label'. --- ChangeLog | 6 ++++++ util/grub-probe.c | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index af48d4039..94b6741d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-07-29 Robert Millan + + * util/grub-probe.c (PRINT_FS_LABEL): New enum value. + (probe): Handle `PRINT_FS_LABEL'. + (main): Handle `-t fs_label'. + 2010-07-29 Robert Millan * configure.ac: Remove grub-mkisofs checks. diff --git a/util/grub-probe.c b/util/grub-probe.c index dff87907a..56cbc5592 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -50,6 +50,7 @@ enum { PRINT_FS, PRINT_FS_UUID, + PRINT_FS_LABEL, PRINT_DRIVE, PRINT_DEVICE, PRINT_PARTMAP, @@ -291,6 +292,16 @@ probe (const char *path, char *device_name) printf ("%s\n", uuid); } + else if (print == PRINT_FS_LABEL) + { + char *label; + if (! fs->label) + grub_util_error ("%s does not support labels", fs->name); + + fs->label (dev, &label); + + printf ("%s\n", label); + } end: if (dev) @@ -326,7 +337,7 @@ Probe device information for a given path (or device, if the -d option is given) \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\ + -t, --target=(fs|fs_uuid|fs_label|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\ @@ -375,6 +386,8 @@ main (int argc, char *argv[]) print = PRINT_FS; else if (!strcmp (optarg, "fs_uuid")) print = PRINT_FS_UUID; + else if (!strcmp (optarg, "fs_label")) + print = PRINT_FS_LABEL; else if (!strcmp (optarg, "drive")) print = PRINT_DRIVE; else if (!strcmp (optarg, "device")) From f7790cdd5d0b97b2246478ec15efb25898fbb253 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 30 Jul 2010 11:27:02 +0200 Subject: [PATCH 463/503] 2010-07-30 Robert Millan * include/grub/emu/misc.h (grub_make_system_path_relative_to_its_root) (xmalloc, xrealloc, xstrdup, xasprintf): Add `warn_unused_result' attribute. * include/grub/misc.h (grub_strdup, grub_strndup, grub_strlen) (grub_xasprintf, grub_xvasprintf): Likewise. * include/grub/emu/misc.h (xasprintf): Remove duplicate prototype. --- ChangeLog | 9 +++++++++ include/grub/emu/misc.h | 11 +++++------ include/grub/misc.h | 10 +++++----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 94b6741d3..4026428a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-07-30 Robert Millan + + * include/grub/emu/misc.h (grub_make_system_path_relative_to_its_root) + (xmalloc, xrealloc, xstrdup, xasprintf): Add + `warn_unused_result' attribute. + * include/grub/misc.h (grub_strdup, grub_strndup, grub_strlen) + (grub_xasprintf, grub_xvasprintf): Likewise. + * include/grub/emu/misc.h (xasprintf): Remove duplicate prototype. + 2010-07-29 Robert Millan * util/grub-probe.c (PRINT_FS_LABEL): New enum value. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index f34cd4287..07257e511 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -26,12 +26,12 @@ extern const char *program_name; void grub_init_all (void); void grub_fini_all (void); -char *grub_make_system_path_relative_to_its_root (const char *path); +char *grub_make_system_path_relative_to_its_root (const char *path) __attribute__ ((warn_unused_result)); -void * EXPORT_FUNC(xmalloc) (grub_size_t size); -void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size); -char * EXPORT_FUNC(xstrdup) (const char *str); -char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); +void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result)); +void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result)); +char * EXPORT_FUNC(xstrdup) (const char *str) __attribute__ ((warn_unused_result)); +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...) __attribute__ ((warn_unused_result)); void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); @@ -45,7 +45,6 @@ int EXPORT_FUNC(vasprintf) (char **buf, const char *fmt, va_list ap); int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); #endif -char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); extern char * canonicalize_file_name (const char *path); #ifdef HAVE_DEVICE_MAPPER diff --git a/include/grub/misc.h b/include/grub/misc.h index 9194ca8ad..eab01b0fb 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -231,10 +231,10 @@ grub_strtol (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); +char *EXPORT_FUNC(grub_strdup) (const char *s) __attribute__ ((warn_unused_result)); +char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) __attribute__ ((warn_unused_result)); void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); -grub_size_t EXPORT_FUNC(grub_strlen) (const char *s); +grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) __attribute__ ((warn_unused_result)); int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); @@ -261,8 +261,8 @@ int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, va_list args); char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args); + __attribute__ ((format (printf, 1, 2))) __attribute__ ((warn_unused_result)); +char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) __attribute__ ((warn_unused_result)); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, From a184f9c80105bafacccbfaea596d406db3bce362 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 30 Jul 2010 21:43:12 +0200 Subject: [PATCH 464/503] 2010-07-30 Robert Millan Enable `grub-probe -t device' resolution on ZFS. * configure.ac: Check for getfsstat(), libzfs and libnvpair. * include/grub/util/libnvpair.h: New file. * include/grub/util/libzfs.h: New file. * kern/emu/getroot.c: Include `' and `'. [HAVE_LIBZFS && HAVE_LIBNVPAIR]: Include `' and `'. [HAVE_GETFSSTAT]: Include `'. (find_mount_point_from_dir): New static function. [HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_root_device_from_libzfs): New function. [HAVE_LIBZFS && HAVE_LIBNVPAIR] (grub_guess_root_device): Use find_root_device_from_libzfs() before ressorting to find_root_device(). * include/grub/util/misc.h (grub_util_init_libzfs): New function prototype. * util/misc.c: Include `'. (grub_util_init_libzfs): New function. [HAVE_LIBZFS] (libzfs_handle): New global variable. [HAVE_LIBZFS] (fini_libzfs): New static function. (grub_util_init_libzfs): New function. * util/grub-probe.c (main): Call grub_util_init_libzfs(). --- ChangeLog | 28 ++++++ configure.ac | 11 ++- include/grub/util/libnvpair.h | 31 +++++++ include/grub/util/libzfs.h | 39 +++++++++ include/grub/util/misc.h | 1 + kern/emu/getroot.c | 155 ++++++++++++++++++++++++++++++++++ util/grub-probe.c | 1 + util/misc.c | 20 +++++ 8 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 include/grub/util/libnvpair.h create mode 100644 include/grub/util/libzfs.h diff --git a/ChangeLog b/ChangeLog index 4026428a7..041f9cadd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2010-07-30 Robert Millan + + Enable `grub-probe -t device' resolution on ZFS. + + * configure.ac: Check for getfsstat(), libzfs and libnvpair. + * include/grub/util/libnvpair.h: New file. + * include/grub/util/libzfs.h: New file. + + * kern/emu/getroot.c: Include `' and `'. + [HAVE_LIBZFS && HAVE_LIBNVPAIR]: Include `' and + `'. + [HAVE_GETFSSTAT]: Include `'. + + (find_mount_point_from_dir): New static function. + [HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_root_device_from_libzfs): New + function. + [HAVE_LIBZFS && HAVE_LIBNVPAIR] (grub_guess_root_device): Use + find_root_device_from_libzfs() before ressorting to find_root_device(). + + * include/grub/util/misc.h (grub_util_init_libzfs): New function + prototype. + * util/misc.c: Include `'. + (grub_util_init_libzfs): New function. + [HAVE_LIBZFS] (libzfs_handle): New global variable. + [HAVE_LIBZFS] (fini_libzfs): New static function. + (grub_util_init_libzfs): New function. + * util/grub-probe.c (main): Call grub_util_init_libzfs(). + 2010-07-30 Robert Millan * include/grub/emu/misc.h (grub_make_system_path_relative_to_its_root) diff --git a/configure.ac b/configure.ac index aa7f3a151..cc97c7f77 100644 --- a/configure.ac +++ b/configure.ac @@ -247,7 +247,7 @@ else fi # Check for functions. -AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf) +AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat) # For opendisk() and getrawpartition() on NetBSD. # Used in util/deviceiter.c and in util/hostdisk.c. @@ -799,6 +799,15 @@ if test x"$device_mapper_excuse" = x ; then [device_mapper_excuse="need devmapper library"]) fi +AC_CHECK_LIB([zfs], [libzfs_init], + [LDFLAGS="$LDFLAGS -lzfs" + AC_DEFINE([HAVE_LIBZFS], [1], + [Define to 1 if you have the ZFS library.])],) +AC_CHECK_LIB([nvpair], [nvlist_print], + [LDFLAGS="$LDFLAGS -lnvpair" + AC_DEFINE([HAVE_LIBNVPAIR], [1], + [Define to 1 if you have the NVPAIR library.])],) + AC_SUBST(ASFLAGS) # Output files. diff --git a/include/grub/util/libnvpair.h b/include/grub/util/libnvpair.h new file mode 100644 index 000000000..c4fe174ea --- /dev/null +++ b/include/grub/util/libnvpair.h @@ -0,0 +1,31 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_LIBNVPAIR_UTIL_HEADER +#define GRUB_LIBNVPAIR_UTIL_HEADER 1 + +#include /* FILE */ + +typedef void nvlist_t; + +int nvlist_lookup_string (nvlist_t *, const char *, char **); +int nvlist_lookup_nvlist (nvlist_t *, const char *, nvlist_t **); +int nvlist_lookup_nvlist_array (nvlist_t *, const char *, nvlist_t ***, unsigned int *); +void nvlist_print (FILE *, nvlist_t *); + +#endif diff --git a/include/grub/util/libzfs.h b/include/grub/util/libzfs.h new file mode 100644 index 000000000..a17c47e20 --- /dev/null +++ b/include/grub/util/libzfs.h @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_LIBZFS_UTIL_HEADER +#define GRUB_LIBZFS_UTIL_HEADER 1 + +#include + +typedef void libzfs_handle_t; +typedef void zpool_handle_t; + +extern libzfs_handle_t *libzfs_init (); +extern void libzfs_fini (libzfs_handle_t *); + +extern zpool_handle_t *zpool_open (libzfs_handle_t *, const char *); +extern void zpool_close (zpool_handle_t *); + +extern int zpool_get_physpath (zpool_handle_t *, const char *); + +extern nvlist_t *zpool_get_config (zpool_handle_t *, nvlist_t **); + +extern libzfs_handle_t *libzfs_handle; + +#endif diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 48dfbb868..699b9cf2c 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -59,5 +59,6 @@ char *make_system_path_relative_to_its_root (const char *path); char *canonicalize_file_name (const char *path); void grub_util_init_nls (void); +void grub_util_init_libzfs (void); #endif /* ! GRUB_UTIL_MISC_HEADER */ diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 58dbac9b4..f2f6311ff 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -20,11 +20,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -41,6 +43,15 @@ # include #endif +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +# include +# include +#endif + +#ifdef HAVE_GETFSSTAT +# include +#endif + #include #include #include @@ -86,6 +97,62 @@ xgetcwd (void) return path; } +static char * +find_mount_point_from_dir (const char *dir) +{ + struct stat st; + typeof (st.st_dev) fs; + char *prev, *next, *slash, *statdir; + + if (stat (dir, &st) == -1) + error (1, errno, "stat (%s)", dir); + + fs = st.st_dev; + + prev = xstrdup (dir); + + while (1) + { + /* Remove last slash. */ + next = xstrdup (prev); + slash = strrchr (next, '/'); + if (! slash) + { + free (next); + free (prev); + return NULL; + } + *slash = '\0'; + + /* A next empty string counts as /. */ + if (next[0] == '\0') + statdir = "/"; + else + statdir = next; + + if (stat (statdir, &st) == -1) + error (1, errno, "stat (%s)", next); + + if (st.st_dev != fs) + { + /* Found mount point. */ + free (next); + return prev; + } + + free (prev); + prev = next; + + /* We've already seen an empty string, which means we + reached /. Nothing left to do. */ + if (prev[0] == '\0') + { + free (prev); + return xstrdup ("/"); + } + } +} + #ifdef __linux__ /* Statting something on a btrfs filesystem always returns a virtual device @@ -166,6 +233,88 @@ find_root_device_from_mountinfo (const char *dir) #endif /* __linux__ */ +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + +/* ZFS has similar problems to those of btrfs (see above). */ +static char * +find_root_device_from_libzfs (const char *dir) +{ + char *device = NULL; + char *poolname = NULL; + char *poolfs = NULL; + char *mnt_point; + char *slash; + + mnt_point = find_mount_point_from_dir (dir); + +#ifdef HAVE_GETFSSTAT + { + int mnt_count = getfsstat (NULL, 0, MNT_WAIT); + if (mnt_count == -1) + error (1, errno, "getfsstat"); + + struct statfs *mnt = xmalloc (mnt_count * sizeof (*mnt)); + + mnt_count = getfsstat (mnt, mnt_count * sizeof (*mnt), MNT_WAIT); + if (mnt_count == -1) + error (1, errno, "getfsstat"); + + unsigned int i; + for (i = 0; i < (unsigned) mnt_count; i++) + if (!strcmp (mnt[i].f_fstypename, "zfs") + && !strcmp (mnt[i].f_mntonname, mnt_point)) + { + poolname = xstrdup (mnt[i].f_mntfromname); + break; + } + + free (mnt); + } +#endif + + if (! poolname) + return NULL; + + slash = strchr (poolname, '/'); + if (slash) + { + *slash = '\0'; + poolfs = slash + 1; + } + + { + zpool_handle_t *zpool; + nvlist_t *nvlist; + nvlist_t **nvlist_array; + unsigned int nvlist_count; + + zpool = zpool_open (libzfs_handle, poolname); + nvlist = zpool_get_config (zpool, NULL); + + if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0) + error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")"); + + if (nvlist_lookup_nvlist_array (nvlist, "children", &nvlist_array, &nvlist_count) != 0) + error (1, errno, "nvlist_lookup_nvlist_array (\"children\")"); + + do + { + assert (nvlist_count > 0); + } while (nvlist_lookup_nvlist_array (nvlist_array[0], "children", + &nvlist_array, &nvlist_count) == 0); + + if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0) + error (1, errno, "nvlist_lookup_string (\"path\")"); + + zpool_close (zpool); + } + + free (poolname); + + return device; +} +#endif + #ifdef __MINGW32__ static char * @@ -458,6 +607,12 @@ grub_guess_root_device (const char *dir) return os_dev; #endif /* __linux__ */ +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + os_dev = find_root_device_from_libzfs (dir); + if (os_dev) + return os_dev; +#endif + if (stat (dir, &st) < 0) grub_util_error ("cannot stat `%s'", dir); diff --git a/util/grub-probe.c b/util/grub-probe.c index 56cbc5592..52f2b3747 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -359,6 +359,7 @@ main (int argc, char *argv[]) set_program_name (argv[0]); grub_util_init_nls (); + grub_util_init_libzfs (); /* Check for options. */ while (1) diff --git a/util/misc.c b/util/misc.c index 91bc25a55..0859197bf 100644 --- a/util/misc.c +++ b/util/misc.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -293,6 +294,25 @@ grub_util_init_nls (void) textdomain (PACKAGE); #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } + +#ifdef HAVE_LIBZFS +libzfs_handle_t *libzfs_handle; + +static void +fini_libzfs (void) +{ + libzfs_fini (libzfs_handle); +} +#endif + +void +grub_util_init_libzfs (void) +{ +#ifdef HAVE_LIBZFS + libzfs_handle = libzfs_init (); + atexit (fini_libzfs); +#endif +} #endif int From c9a00aeeaa0d9c4d6b254fe2e221b67b951a48e7 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 30 Jul 2010 22:01:10 +0200 Subject: [PATCH 465/503] 2010-07-30 Robert Millan * include/grub/emu/misc.h: Add missing license header. --- ChangeLog | 4 ++++ include/grub/emu/misc.h | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index 041f9cadd..86aba2914 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-30 Robert Millan + + * include/grub/emu/misc.h: Add missing license header. + 2010-07-30 Robert Millan Enable `grub-probe -t device' resolution on ZFS. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 07257e511..dc48d91a8 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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_EMU_MISC_H #define GRUB_EMU_MISC_H 1 From 3169f4c76a37a1545d7382a5dd483e36d00da5c3 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 31 Jul 2010 12:22:01 +0200 Subject: [PATCH 466/503] 2010-07-31 Robert Millan * configure.ac: Check for `libzfs.h' and `libnvpair.h'. * include/grub/util/libnvpair.h: Include `'. [HAVE_LIBNVPAIR_H]: Include `' instead of declaring libnvpair prototypes ourselves. * include/grub/util/libzfs.h: Include `'. [HAVE_LIBZFS_H]: Include `' instead of declaring libzfs prototypes ourselves. (libzfs_handle): Moved to ... * include/grub/util/misc.h (libzfs_handle): ... here. Include `'. --- ChangeLog | 15 +++++++++++++++ configure.ac | 3 ++- include/grub/util/libnvpair.h | 8 ++++++++ include/grub/util/libzfs.h | 8 +++++++- include/grub/util/misc.h | 3 +++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 86aba2914..58b821da9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-07-31 Robert Millan + + * configure.ac: Check for `libzfs.h' and `libnvpair.h'. + + * include/grub/util/libnvpair.h: Include `'. + [HAVE_LIBNVPAIR_H]: Include `' instead of + declaring libnvpair prototypes ourselves. + * include/grub/util/libzfs.h: Include `'. + [HAVE_LIBZFS_H]: Include `' instead of + declaring libzfs prototypes ourselves. + + (libzfs_handle): Moved to ... + * include/grub/util/misc.h (libzfs_handle): ... here. + Include `'. + 2010-07-30 Robert Millan * include/grub/emu/misc.h: Add missing license header. diff --git a/configure.ac b/configure.ac index cc97c7f77..6169a2fb5 100644 --- a/configure.ac +++ b/configure.ac @@ -246,8 +246,9 @@ else AC_PATH_PROG(HELP2MAN, help2man) fi -# Check for functions. +# Check for functions and headers. AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat) +AC_CHECK_HEADERS(libzfs.h libnvpair.h) # For opendisk() and getrawpartition() on NetBSD. # Used in util/deviceiter.c and in util/hostdisk.c. diff --git a/include/grub/util/libnvpair.h b/include/grub/util/libnvpair.h index c4fe174ea..26f7e9d0f 100644 --- a/include/grub/util/libnvpair.h +++ b/include/grub/util/libnvpair.h @@ -19,6 +19,12 @@ #ifndef GRUB_LIBNVPAIR_UTIL_HEADER #define GRUB_LIBNVPAIR_UTIL_HEADER 1 +#include + +#ifdef HAVE_LIBNVPAIR_H +#include +#else /* ! HAVE_LIBNVPAIR_H */ + #include /* FILE */ typedef void nvlist_t; @@ -28,4 +34,6 @@ int nvlist_lookup_nvlist (nvlist_t *, const char *, nvlist_t **); int nvlist_lookup_nvlist_array (nvlist_t *, const char *, nvlist_t ***, unsigned int *); void nvlist_print (FILE *, nvlist_t *); +#endif /* ! HAVE_LIBNVPAIR_H */ + #endif diff --git a/include/grub/util/libzfs.h b/include/grub/util/libzfs.h index a17c47e20..9fbfd40d1 100644 --- a/include/grub/util/libzfs.h +++ b/include/grub/util/libzfs.h @@ -19,6 +19,12 @@ #ifndef GRUB_LIBZFS_UTIL_HEADER #define GRUB_LIBZFS_UTIL_HEADER 1 +#include + +#ifdef HAVE_LIBZFS_H +#include +#else /* ! HAVE_LIBZFS_H */ + #include typedef void libzfs_handle_t; @@ -34,6 +40,6 @@ extern int zpool_get_physpath (zpool_handle_t *, const char *); extern nvlist_t *zpool_get_config (zpool_handle_t *, nvlist_t **); -extern libzfs_handle_t *libzfs_handle; +#endif /* ! HAVE_LIBZFS_H */ #endif diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 699b9cf2c..3614c79c2 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -29,6 +29,7 @@ #include #include #include +#include char *grub_util_get_path (const char *dir, const char *file); size_t grub_util_get_fp_size (FILE *fp); @@ -59,6 +60,8 @@ char *make_system_path_relative_to_its_root (const char *path); char *canonicalize_file_name (const char *path); void grub_util_init_nls (void); + void grub_util_init_libzfs (void); +extern libzfs_handle_t *libzfs_handle; #endif /* ! GRUB_UTIL_MISC_HEADER */ From 8072efebf210fbc610ae852750e3f400305dfc69 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 31 Jul 2010 18:45:57 +0200 Subject: [PATCH 467/503] 2010-07-31 Robert Millan * kern/emu/misc.c: Add missing license header. --- ChangeLog | 4 ++++ kern/emu/misc.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index 58b821da9..24303ff17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-31 Robert Millan + + * kern/emu/misc.c: Add missing license header. + 2010-07-31 Robert Millan * configure.ac: Check for `libzfs.h' and `libnvpair.h'. diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 38395fca8..851da7a07 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 From 3710bb6b96ba84767e9315b8eecfd31c8b2386de Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 1 Aug 2010 02:14:07 +0200 Subject: [PATCH 468/503] 2010-07-31 Robert Millan * util/grub.d/10_kfreebsd.in: Make module handling more generic. --- ChangeLog | 4 ++++ util/grub.d/10_kfreebsd.in | 25 ++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24303ff17..249256083 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-07-31 Robert Millan + + * util/grub.d/10_kfreebsd.in: Make module handling more generic. + 2010-07-31 Robert Millan * kern/emu/misc.c: Add missing license header. diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 9915abdf1..f32da3013 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -51,6 +51,10 @@ kfreebsd_entry () if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi + if [ -z "${prepare_module_dir_cache}" ]; then + prepare_module_dir_cache="$(prepare_grub_to_access_device $(grub-probe -t device "${module_dir}") | sed -e "s/^/\t/")" + fi + printf '%s\n' "${prepare_boot_cache}" cat << EOF echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})' @@ -63,9 +67,10 @@ EOF EOF fi - if test -n "${acpi_ko}" ; then + if test -e "${module_dir}/acpi.ko" ; then + printf '%s\n' "${prepare_module_dir_cache}" cat << EOF - kfreebsd_module_elf ${acpi_ko_rel_dirname}/${acpi_ko_basename} + kfreebsd_module_elf ${module_dir_rel}/acpi.ko EOF fi @@ -103,19 +108,17 @@ while [ "x$list" != "x" ] ; do version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"` alt_version=`echo $version | sed -e "s,\.old$,,g"` - acpi_ko= - for i in "/lib/modules/${version}/acpi.ko" "/lib/modules/${alt_version}/acpi.ko" \ - "/boot/kernel/acpi.ko"; do + module_dir= + for i in "/lib/modules/${version}" "/lib/modules/${alt_version}" \ + "/boot/kernel"; do if test -e "$i" ; then - acpi_ko="$i" + module_dir="$i" break fi done - if test -n "${acpi_ko}" ; then - echo "Found ACPI module: ${acpi_ko}" >&2 - acpi_ko_basename=`basename ${acpi_ko}` - acpi_ko_dirname=`dirname ${acpi_ko}` - acpi_ko_rel_dirname=`make_system_path_relative_to_its_root $acpi_ko_dirname` + if test -n "${module_dir}" ; then + echo "Found kernel module directory: ${module_dir}" >&2 + module_dir_rel=$(make_system_path_relative_to_its_root $module_dir) fi kfreebsd_entry "${OS}" "${version}" From ebf53056b8e17487c9f56effe9130f5772a93e02 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 1 Aug 2010 14:47:14 +0200 Subject: [PATCH 469/503] 2010-08-01 Robert Millan * kern/emu/getroot.c: Include `'. --- ChangeLog | 4 ++++ kern/emu/getroot.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 249256083..f34ed35c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-01 Robert Millan + + * kern/emu/getroot.c: Include `'. + 2010-07-31 Robert Millan * util/grub.d/10_kfreebsd.in: Make module handling more generic. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index f2f6311ff..6caae08e6 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef __GNU__ #include From ce04ef47e2ef22cc3886b88beba2e58e8d115702 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 1 Aug 2010 08:54:10 -0500 Subject: [PATCH 470/503] * util/grub.d/20_linux_xen.in: Don't use UUID for LVM root (matching util/grub.d/10_linux.in). Fixes Debian bug #591093. --- ChangeLog | 5 +++++ util/grub.d/20_linux_xen.in | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f34ed35c9..abe698574 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-01 Colin Watson + + * util/grub.d/20_linux_xen.in: Don't use UUID for LVM root (matching + util/grub.d/10_linux.in). Fixes Debian bug #591093. + 2010-08-01 Robert Millan * kern/emu/getroot.c: Include `'. diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 8612c96b0..e631c0a4a 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -44,7 +44,8 @@ case ${GRUB_DEVICE} in esac if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ - || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then + || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ + || uses_abstraction "${GRUB_DEVICE}" lvm; then LINUX_ROOT_DEVICE=${GRUB_DEVICE} else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} From deb0caa38ebc69aa7135d56896a6e61d0642ba3c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 1 Aug 2010 15:23:44 +0200 Subject: [PATCH 471/503] 2010-08-01 Robert Millan Prevent accidental use of uninitialized libzfs_handle. * util/grub-probe.c (main): Move grub_util_init_libzfs() call to ... * kern/emu/getroot.c (find_root_device_from_libzfs): ... here. * util/misc.c (grub_util_init_libzfs): Make this function idempotent. --- ChangeLog | 8 ++++++++ kern/emu/getroot.c | 2 ++ util/grub-probe.c | 1 - util/misc.c | 7 +++++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index abe698574..20094fec8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-08-01 Robert Millan + + Prevent accidental use of uninitialized libzfs_handle. + + * util/grub-probe.c (main): Move grub_util_init_libzfs() call to ... + * kern/emu/getroot.c (find_root_device_from_libzfs): ... here. + * util/misc.c (grub_util_init_libzfs): Make this function idempotent. + 2010-08-01 Colin Watson * util/grub.d/20_linux_xen.in: Don't use UUID for LVM root (matching diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6caae08e6..f8eda2294 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -289,6 +289,8 @@ find_root_device_from_libzfs (const char *dir) nvlist_t **nvlist_array; unsigned int nvlist_count; + grub_util_init_libzfs (); + zpool = zpool_open (libzfs_handle, poolname); nvlist = zpool_get_config (zpool, NULL); diff --git a/util/grub-probe.c b/util/grub-probe.c index 52f2b3747..56cbc5592 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -359,7 +359,6 @@ main (int argc, char *argv[]) set_program_name (argv[0]); grub_util_init_nls (); - grub_util_init_libzfs (); /* Check for options. */ while (1) diff --git a/util/misc.c b/util/misc.c index 0859197bf..2eff256bf 100644 --- a/util/misc.c +++ b/util/misc.c @@ -309,8 +309,11 @@ void grub_util_init_libzfs (void) { #ifdef HAVE_LIBZFS - libzfs_handle = libzfs_init (); - atexit (fini_libzfs); + if (! libzfs_handle) + { + libzfs_handle = libzfs_init (); + atexit (fini_libzfs); + } #endif } #endif From 7decd202a72cbed9d1e1d445d6fbea9532703866 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 1 Aug 2010 09:44:36 -0500 Subject: [PATCH 472/503] * kern/misc.c (grub_memset): Optimise to reduce cache stalls. Also-By: Colin Watson --- ChangeLog | 5 +++++ kern/misc.c | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 20094fec8..d00fd9d51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-01 Vladimir Serbinenko +2010-08-01 Colin Watson + + * kern/misc.c (grub_memset): Optimise to reduce cache stalls. + 2010-08-01 Robert Millan Prevent accidental use of uninitialized libzfs_handle. diff --git a/kern/misc.c b/kern/misc.c index c13c96e30..b37ef230c 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -518,12 +518,39 @@ grub_strndup (const char *s, grub_size_t n) } void * -grub_memset (void *s, int c, grub_size_t n) +grub_memset (void *s, int c, grub_size_t len) { - unsigned char *p = (unsigned char *) s; + void *p = s; + grub_uint8_t pattern8 = c; - while (n--) - *p++ = (unsigned char) c; + if (len >= 3 * sizeof (unsigned long)) + { + unsigned long patternl = 0; + grub_size_t i; + + for (i = 0; i < sizeof (unsigned long); i++) + patternl |= ((unsigned long) pattern8) << (8 * i); + + while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1))) + { + *(grub_uint8_t *) p = pattern8; + p = (grub_uint8_t *) p + 1; + len--; + } + while (len >= sizeof (unsigned long)) + { + *(unsigned long *) p = patternl; + p = (unsigned long *) p + 1; + len -= sizeof (unsigned long); + } + } + + while (len > 0) + { + *(grub_uint8_t *) p = pattern8; + p = (grub_uint8_t *) p + 1; + len--; + } return s; } From 2cfb45df5ed7be7b55c69dc0f809343e189afdb9 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 1 Aug 2010 11:25:09 -0500 Subject: [PATCH 473/503] * docs/grub.texi (Simple configuration): Document GRUB_CMDLINE_XEN and GRUB_CMDLINE_XEN_DEFAULT. Recommend setting GRUB_GFXPAYLOAD_LINUX=text rather than unsetting it in order to disable gfxpayload. (Shell-like scripting): Add real content. (Serial terminal): Suggest `terminal_input serial; terminal_output serial' rather than putting the two commands on separate lines, since console input will be inoperative after the first command. (menuentry): Document --class, --users, and --hotkey options. (terminfo): Describe what `visually-ordered UTF-8' means (thanks, Vladimir Serbinenko). --- ChangeLog | 14 ++++ docs/grub.texi | 182 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 186 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index d00fd9d51..1c1533841 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-08-01 Colin Watson + + * docs/grub.texi (Simple configuration): Document GRUB_CMDLINE_XEN + and GRUB_CMDLINE_XEN_DEFAULT. Recommend setting + GRUB_GFXPAYLOAD_LINUX=text rather than unsetting it in order to + disable gfxpayload. + (Shell-like scripting): Add real content. + (Serial terminal): Suggest `terminal_input serial; terminal_output + serial' rather than putting the two commands on separate lines, + since console input will be inoperative after the first command. + (menuentry): Document --class, --users, and --hotkey options. + (terminfo): Describe what `visually-ordered UTF-8' means (thanks, + Vladimir Serbinenko). + 2010-08-01 Vladimir Serbinenko 2010-08-01 Colin Watson diff --git a/docs/grub.texi b/docs/grub.texi index a191ef9ef..583cf98cb 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1062,6 +1062,11 @@ only to the default menu entry, after those listed in As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for NetBSD. +@item GRUB_CMDLINE_XEN +@itemx GRUB_CMDLINE_XEN_DEFAULT +As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for +Linux and Xen. + @item GRUB_DISABLE_LINUX_UUID Normally, @command{grub-mkconfig} will generate menu entries that use universally-unique identifiers (UUIDs) to identify the root filesystem to @@ -1113,8 +1118,8 @@ try several modes in sequence. Depending on your kernel, your distribution, your graphics card, and the phase of the moon, note that using this option may cause GNU/Linux to suffer from various display problems, particularly during the early part of the -boot sequence. If you have problems, simply unset this option and GRUB will -tell Linux to boot in normal text mode. +boot sequence. If you have problems, set this option to @samp{text} and +GRUB will tell Linux to boot in normal text mode. @item GRUB_DISABLE_OS_PROBER Normally, @command{grub-mkconfig} will try to use the external @@ -1143,6 +1148,142 @@ that file, making sure to leave at least the first two lines intact. @node Shell-like scripting @section Writing full configuration files directly +@c Some of this section is derived from the GNU Bash manual page, also +@c copyrighted by the FSF. + +@file{grub.cfg} is written in GRUB's built-in scripting language, which has +a syntax quite similar to that of GNU Bash and other Bourne shell +derivatives. + +@heading Words + +A @dfn{word} is a sequence of characters considered as a single unit by +GRUB. Words are separated by @dfn{metacharacters}, which are the following +plus space, tab, and newline: + +@example +@{ @} | & $ ; < > +@end example + +Quoting may be used to include metacharacters in words; see below. + +@heading Reserved words + +Reserved words have a special meaning to GRUB. The following words are +recognised as reserved when unquoted and either the first word of a simple +command or the third word of a @code{for} command: + +@example +! [[ ]] @{ @} +case do done elif else esac fi for function +if in menuentry select then time until while +@end example + +Not all of these reserved words have a useful purpose yet; some are reserved +for future expansion. + +@heading Quoting + +Quoting is used to remove the special meaning of certain characters or +words. It can be used to treat metacharacters as part of a word, to prevent +reserved words from being recognised as such, and to prevent variable +expansion. + +There are three quoting mechanisms: the escape character, single quotes, and +double quotes. + +A non-quoted backslash (\) is the @dfn{escape character}. It preserves the +literal value of the next character that follows, with the exception of +newline. + +Enclosing characters in single quotes preserves the literal value of each +character within the quotes. A single quote may not occur between single +quotes, even when preceded by a backslash. + +Enclosing characters in double quotes preserves the literal value of all +characters within the quotes, with the exception of @samp{$} and @samp{\}. +The @samp{$} character retains its special meaning within double quotes. +The backslash retains its special meaning only when followed by one of the +following characters: @samp{$}, @samp{"}, @samp{\}, or newline. A +backslash-newline pair is treated as a line continuation (that is, it is +removed from the input stream and effectively ignored). A double quote may +be quoted within double quotes by preceding it with a backslash. + +@heading Variable expansion + +The @samp{$} character introduces variable expansion. The variable name to +be expanded may be enclosed in braces, which are optional but serve to +protect the variable to be expanded from characters immediately following it +which could be interpreted as part of the name. + +Normal variable names begin with an alphabetic character, followed by zero +or more alphanumeric characters. + +Positional variable names consist of one or more digits. These are reserved +for future expansion. + +The special variable name @samp{?} expands to the exit status of the most +recently executed command. + +@heading Comments + +A word beginning with @samp{#} causes that word and all remaining characters +on that line to be ignored. + +@heading Simple commands + +A @dfn{simple command} is a sequence of words separated by spaces or tabs +and terminated by a semicolon or a newline. The first word specifies the +command to be executed. The remaining words are passed as arguments to the +invoked command. + +The return value of a simple command is its exit status. + +@heading Compound commands + +A @dfn{compound command} is one of the following: + +@table @asis +@item for @var{name} in @var{word} @dots{}; do @var{list}; done +The list of words following @code{in} is expanded, generating a list of +items. The variable @var{name} is set to each element of this list in turn, +and @var{list} is executed each time. The return value is the exit status +of the last command that executes. If the expansion of the items following +@code{in} results in an empty list, no commands are executed, and the return +status is 0. + +@item if @var{list}; then @var{list}; [elif @var{list}; then @var{list};] @dots{} [else @var{list};] fi +The @code{if} @var{list} is executed. If its exit status is zero, the +@code{then} @var{list} is executed. Otherwise, each @code{elif} @var{list} +is executed in turn, and if its exit status is zero, the corresponding +@code{then} @var{list} is executed and the command completes. Otherwise, +the @code{else} @var{list} is executed, if present. The exit status is the +exit status of the last command executed, or zero if no condition tested +true. + +@item while @var{cond}; do @var{list}; done +@itemx until @var{cond}; do @var{list}; done +The @code{while} command continuously executes the @code{do} @var{list} as +long as the last command in @var{cond} returns an exit status of zero. The +@code{until} command is identical to the @code{while} command, except that +the test is negated; the @code{do} @var{list} is executed as long as the +last command in @var{cond} returns a non-zero exit status. The exit status +of the @code{while} and @code{until} commands is the exit status of the last +@code{do} @var{list} command executed, or zero if none was executed. + +@item function @var{name} @{ @var{command}; @dots{} @} +This defines a function named @var{name}. The @dfn{body} of the function is +the list of commands within braces, each of which must be terminated with a +semicolon or a newline. This list of commands will be executed whenever +@var{name} is specified as the name of a simple command. Function +definitions do not affect the exit status in @code{$?}. When executed, the +exit status of a function is the exit status of the last command executed in +the body. + +@item menuentry @var{title} [@option{--class=class} @dots{}] [@option{--users=users}] [@option{--hotkey=key}] @{ @var{command}; @dots{} @} +@xref{menuentry}. +@end table + @node Embedded configuration @section Embedding a configuration file into GRUB @@ -1308,8 +1449,7 @@ simple. Here is an example: @example @group grub> @kbd{serial --unit=0 --speed=9600} -grub> @kbd{terminal_input serial} -grub> @kbd{terminal_output serial} +grub> @kbd{terminal_input serial; terminal_output serial} @end group @end example @@ -1320,11 +1460,14 @@ command accepts many other options, so please refer to @ref{serial}, for more details. The commands @command{terminal_input} (@pxref{terminal_input}) and -@command{terminal_output} (@pxref{terminal_output} choose which type of +@command{terminal_output} (@pxref{terminal_output}) choose 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. +you press any key will be selected as a GRUB terminal. In the example above, +note that you need to put both commands on the same command line, as you +will lose the ability to type commands on the console after the first +command. However, note that GRUB assumes that your terminal emulator is compatible with VT100 by default. This is true for most terminal @@ -1789,9 +1932,26 @@ These commands can only be used in the menu: @node menuentry @subsection menuentry -@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. +@deffn Command menuentry @var{title} @ + [@option{--class=class} @dots{}] [@option{--users=users}] @ + [@option{--hotkey=key}] @ + @{ @var{command}; @dots{} @} +This defines a GRUB menu entry named @var{title}. When this entry is +selected from the menu, GRUB will set the @var{chosen} environment variable +to @var{title}, execute the list of commands given within braces, and if the +last command in the list returned successfully and a kernel was loaded it +will execute the @command{boot} command. + +The @option{--class} option may be used any number of times to group menu +entries into classes. Menu themes may display different classes using +different styles. + +The @option{--users} option grants specific users access to specific menu +entries. @xref{Security}. + +The @option{--hotkey} option associates a hotkey with a menu entry. +@var{key} may be a single letter, or one of the aliases @samp{backspace}, +@samp{tab}, or @samp{delete}. @end deffn @@ -1885,7 +2045,9 @@ The @option{-a} (@option{--ascii}), @option{-u} (@option{--utf8}), and @option{-v} (@option{--visual-utf8}) options control how non-ASCII text is displayed. @option{-a} specifies an ASCII-only terminal; @option{-u} specifies logically-ordered UTF-8; and @option{-v} specifies -visually-ordered UTF-8. +"visually-ordered UTF-8" (in other words, arranged such that a terminal +emulator without bidirectional text support will display right-to-left text +in the proper order; this is not really proper UTF-8, but a workaround). If no option or terminal type is specified, the current terminal type is printed. From 6eea041aa4dae2be3ffe42786dce894d8d89dfba Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 1 Aug 2010 11:28:12 -0500 Subject: [PATCH 474/503] * script/yylex.l (NAME): Remove [:digit:], redundant with [:alnum:]. --- ChangeLog | 4 ++++ script/yylex.l | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1c1533841..83ac0b37b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-01 Colin Watson + + * script/yylex.l (NAME): Remove [:digit:], redundant with [:alnum:]. + 2010-08-01 Colin Watson * docs/grub.texi (Simple configuration): Document GRUB_CMDLINE_XEN diff --git a/script/yylex.l b/script/yylex.l index 7d4ea9e4e..e9659832b 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -116,7 +116,7 @@ COMMENT #.*$ CHAR [^{}|&$;<> \t\n\'\"\\] DIGITS [[:digit:]]+ -NAME [[:alpha:]_][[:alnum:][:digit:]_]* +NAME [[:alpha:]_][[:alnum:]_]* ESC \\. VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\} From ea9be8eadb4d899eb6bc740b360de292695aacf9 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 1 Aug 2010 11:30:03 -0500 Subject: [PATCH 475/503] * util/grub-mkrescue.in: Remove ${efi_dir} after building efi.img. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 83ac0b37b..9729f71d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-01 Colin Watson + + * util/grub-mkrescue.in: Remove ${efi_dir} after building efi.img. + 2010-08-01 Colin Watson * script/yylex.l (NAME): Remove [:digit:], redundant with [:alnum:]. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index e498acee7..b7d9eb4eb 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -296,6 +296,7 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ + rm -rf ${efi_dir} grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" fi From 8687cf071e646a5c949b7cbcf14f6ea9334ec466 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 1 Aug 2010 16:11:27 +0200 Subject: [PATCH 476/503] * kern/emu/getroot.c (find_mount_point_from_dir): Compile only if [HAVE_LIBZFS && HAVE_LIBNVPAIR] --- ChangeLog | 7 ++++++- kern/emu/getroot.c | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9729f71d8..2e8c0daa5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-01 Vladimir Serbinenko + + * kern/emu/getroot.c (find_mount_point_from_dir): Compile only if + [HAVE_LIBZFS && HAVE_LIBNVPAIR] + 2010-08-01 Colin Watson * util/grub-mkrescue.in: Remove ${efi_dir} after building efi.img. @@ -41,7 +46,7 @@ 2010-08-01 Robert Millan * kern/emu/getroot.c: Include `'. - + 2010-07-31 Robert Millan * util/grub.d/10_kfreebsd.in: Make module handling more generic. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index f8eda2294..032608d1b 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -98,6 +98,8 @@ xgetcwd (void) return path; } +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + static char * find_mount_point_from_dir (const char *dir) { @@ -154,6 +156,8 @@ find_mount_point_from_dir (const char *dir) } } +#endif + #ifdef __linux__ /* Statting something on a btrfs filesystem always returns a virtual device From 553df63d76cf4a5b6fa63042021320e5b6d6a5d4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 1 Aug 2010 21:01:05 +0200 Subject: [PATCH 477/503] * lib/arg.c (grub_arg_show_help): Add the necessary spacing. --- ChangeLog | 4 ++++ lib/arg.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e8c0daa5..bc6b8fd18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-01 Vladimir Serbinenko + + * lib/arg.c (grub_arg_show_help): Add the necessary spacing. + 2010-08-01 Vladimir Serbinenko * kern/emu/getroot.c (find_mount_point_from_dir): Compile only if diff --git a/lib/arg.c b/lib/arg.c index 400314d30..a9b8a520e 100644 --- a/lib/arg.c +++ b/lib/arg.c @@ -144,8 +144,10 @@ grub_arg_show_help (grub_extcmd_t cmd) } } - /* FIXME: add spacing back. */ - grub_xputs (_(opt->doc)); + while (spacing--) + grub_xputs (" "); + + grub_printf ("%s\n", _(opt->doc)); switch (opt->shortarg) { From 8bfe31d82b187f4dbaa9df652bd170bd5915c818 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 1 Aug 2010 16:41:46 -0500 Subject: [PATCH 478/503] * include/grub/util/libzfs.h (libzfs_init): Set argument list to (void) rather than () so that this is a proper prototype. --- ChangeLog | 5 +++++ include/grub/util/libzfs.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bc6b8fd18..daf5517dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-01 Colin Watson + + * include/grub/util/libzfs.h (libzfs_init): Set argument list to + (void) rather than () so that this is a proper prototype. + 2010-08-01 Vladimir Serbinenko * lib/arg.c (grub_arg_show_help): Add the necessary spacing. diff --git a/include/grub/util/libzfs.h b/include/grub/util/libzfs.h index 9fbfd40d1..0500f70d7 100644 --- a/include/grub/util/libzfs.h +++ b/include/grub/util/libzfs.h @@ -30,7 +30,7 @@ typedef void libzfs_handle_t; typedef void zpool_handle_t; -extern libzfs_handle_t *libzfs_init (); +extern libzfs_handle_t *libzfs_init (void); extern void libzfs_fini (libzfs_handle_t *); extern zpool_handle_t *zpool_open (libzfs_handle_t *, const char *); From c882acc031c3ee096c01ee73963ab4628155f3cc Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 1 Aug 2010 22:59:02 +0200 Subject: [PATCH 479/503] 2010-08-01 Robert Millan * include/grub/emu/misc.h (grub_find_mount_point_from_dir) (grub_find_zpool_from_mount_point): New function prototypes. * kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `' to ... * kern/emu/misc.c [HAVE_GETFSSTAT]: ... here. * kern/emu/getroot.c (find_mount_point_from_dir): Move to ... * kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove `static' attribute. * kern/emu/getroot.c (find_root_device_from_libzfs): Split code for finding zpool from mount point into ... * kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this. * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When requested path is part of a ZFS pool, use grub_find_zpool_from_mount_point() to detect its filesystem name, and generate a path with `/fsname@path' syntax. --- ChangeLog | 42 ++++++++++++ include/grub/emu/misc.h | 8 ++- kern/emu/getroot.c | 112 +++----------------------------- kern/emu/misc.c | 140 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 196 insertions(+), 106 deletions(-) diff --git a/ChangeLog b/ChangeLog index daf5517dc..2956129b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-08-01 Robert Millan + + * include/grub/emu/misc.h (grub_find_mount_point_from_dir) + (grub_find_zpool_from_mount_point): New function prototypes. + + * kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `' to ... + * kern/emu/misc.c [HAVE_GETFSSTAT]: ... here. + + * kern/emu/getroot.c (find_mount_point_from_dir): Move to ... + * kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove + `static' attribute. + + * kern/emu/getroot.c (find_root_device_from_libzfs): Split code for + finding zpool from mount point into ... + * kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this. + + * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When + requested path is part of a ZFS pool, use + grub_find_zpool_from_mount_point() to detect its filesystem name, + and generate a path with `/fsname@path' syntax. + 2010-08-01 Colin Watson * include/grub/util/libzfs.h (libzfs_init): Set argument list to @@ -39,6 +60,27 @@ * kern/misc.c (grub_memset): Optimise to reduce cache stalls. +2010-08-01 Robert Millan + + * include/grub/emu/misc.h (grub_find_mount_point_from_dir) + (grub_find_zpool_from_mount_point): New function prototypes. + + * kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `' to ... + * kern/emu/misc.c [HAVE_GETFSSTAT]: ... here. + + * kern/emu/getroot.c (find_mount_point_from_dir): Move to ... + * kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove + `static' attribute. + + * kern/emu/getroot.c (find_root_device_from_libzfs): Split code for + finding zpool from mount point into ... + * kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this. + + * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When + requested path is part of a ZFS pool, use + grub_find_zpool_from_mount_point() to detect its filesystem name, + and generate a path with `/fsname@path' syntax. + 2010-08-01 Robert Millan Prevent accidental use of uninitialized libzfs_handle. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index dc48d91a8..5047a9406 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -44,7 +44,13 @@ extern const char *program_name; void grub_init_all (void); void grub_fini_all (void); -char *grub_make_system_path_relative_to_its_root (const char *path) __attribute__ ((warn_unused_result)); +char *grub_find_mount_point_from_dir (const char *dir) + __attribute__ ((warn_unused_result)); +void grub_find_zpool_from_mount_point (const char *mnt_point, + char **poolname, char **poolfs); + +char *grub_make_system_path_relative_to_its_root (const char *path) + __attribute__ ((warn_unused_result)); void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result)); void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result)); diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 032608d1b..32044536d 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -49,10 +49,6 @@ # include #endif -#ifdef HAVE_GETFSSTAT -# include -#endif - #include #include #include @@ -98,66 +94,6 @@ xgetcwd (void) return path; } -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) - -static char * -find_mount_point_from_dir (const char *dir) -{ - struct stat st; - typeof (st.st_dev) fs; - char *prev, *next, *slash, *statdir; - - if (stat (dir, &st) == -1) - error (1, errno, "stat (%s)", dir); - - fs = st.st_dev; - - prev = xstrdup (dir); - - while (1) - { - /* Remove last slash. */ - next = xstrdup (prev); - slash = strrchr (next, '/'); - if (! slash) - { - free (next); - free (prev); - return NULL; - } - *slash = '\0'; - - /* A next empty string counts as /. */ - if (next[0] == '\0') - statdir = "/"; - else - statdir = next; - - if (stat (statdir, &st) == -1) - error (1, errno, "stat (%s)", next); - - if (st.st_dev != fs) - { - /* Found mount point. */ - free (next); - return prev; - } - - free (prev); - prev = next; - - /* We've already seen an empty string, which means we - reached /. Nothing left to do. */ - if (prev[0] == '\0') - { - free (prev); - return xstrdup ("/"); - } - } -} - -#endif - #ifdef __linux__ /* Statting something on a btrfs filesystem always returns a virtual device @@ -239,52 +175,20 @@ find_root_device_from_mountinfo (const char *dir) #endif /* __linux__ */ #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) - -/* ZFS has similar problems to those of btrfs (see above). */ static char * find_root_device_from_libzfs (const char *dir) { - char *device = NULL; - char *poolname = NULL; - char *poolfs = NULL; + char *device; + char *poolname; + char *poolfs; char *mnt_point; - char *slash; - - mnt_point = find_mount_point_from_dir (dir); - -#ifdef HAVE_GETFSSTAT - { - int mnt_count = getfsstat (NULL, 0, MNT_WAIT); - if (mnt_count == -1) - error (1, errno, "getfsstat"); - - struct statfs *mnt = xmalloc (mnt_count * sizeof (*mnt)); - - mnt_count = getfsstat (mnt, mnt_count * sizeof (*mnt), MNT_WAIT); - if (mnt_count == -1) - error (1, errno, "getfsstat"); - - unsigned int i; - for (i = 0; i < (unsigned) mnt_count; i++) - if (!strcmp (mnt[i].f_fstypename, "zfs") - && !strcmp (mnt[i].f_mntonname, mnt_point)) - { - poolname = xstrdup (mnt[i].f_mntfromname); - break; - } - - free (mnt); - } -#endif + mnt_point = grub_find_mount_point_from_dir (dir); + grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs); if (! poolname) - return NULL; - - slash = strchr (poolname, '/'); - if (slash) { - *slash = '\0'; - poolfs = slash + 1; + free (mnt_point); + return NULL; } { @@ -317,6 +221,8 @@ find_root_device_from_libzfs (const char *dir) } free (poolname); + if (poolfs) + free (poolfs); return device; } diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 851da7a07..0d71ef3d6 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,15 @@ # include #endif +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +# include +# include +#endif + +#ifdef HAVE_GETFSSTAT +# include +#endif + int verbosity; void @@ -236,6 +246,114 @@ get_win32_path (const char *path) } #endif +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +/* Not ZFS-specific in itself, but for now it's only used by ZFS-related code. */ +char * +grub_find_mount_point_from_dir (const char *dir) +{ + struct stat st; + typeof (st.st_dev) fs; + char *prev, *next, *slash, *statdir; + + if (stat (dir, &st) == -1) + error (1, errno, "stat (%s)", dir); + + fs = st.st_dev; + + prev = xstrdup (dir); + + while (1) + { + /* Remove last slash. */ + next = xstrdup (prev); + slash = strrchr (next, '/'); + if (! slash) + { + free (next); + free (prev); + return NULL; + } + *slash = '\0'; + + /* A next empty string counts as /. */ + if (next[0] == '\0') + statdir = "/"; + else + statdir = next; + + if (stat (statdir, &st) == -1) + error (1, errno, "stat (%s)", next); + + if (st.st_dev != fs) + { + /* Found mount point. */ + free (next); + return prev; + } + + free (prev); + prev = next; + + /* We've already seen an empty string, which means we + reached /. Nothing left to do. */ + if (prev[0] == '\0') + { + free (prev); + return xstrdup ("/"); + } + } +} +#endif + +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + +/* ZFS has similar problems to those of btrfs (see above). */ +void +grub_find_zpool_from_mount_point (const char *mnt_point, char **poolname, char **poolfs) +{ + char *slash; + + *poolname = *poolfs = NULL; + +#ifdef HAVE_GETFSSTAT + { + int mnt_count = getfsstat (NULL, 0, MNT_WAIT); + if (mnt_count == -1) + error (1, errno, "getfsstat"); + + struct statfs *mnt = xmalloc (mnt_count * sizeof (*mnt)); + + mnt_count = getfsstat (mnt, mnt_count * sizeof (*mnt), MNT_WAIT); + if (mnt_count == -1) + error (1, errno, "getfsstat"); + + unsigned int i; + for (i = 0; i < (unsigned) mnt_count; i++) + if (!strcmp (mnt[i].f_fstypename, "zfs") + && !strcmp (mnt[i].f_mntonname, mnt_point)) + { + *poolname = xstrdup (mnt[i].f_mntfromname); + break; + } + + free (mnt); + } +#endif + + if (! *poolname) + return; + + slash = strchr (*poolname, '/'); + if (slash) + { + *slash = '\0'; + *poolfs = xstrdup (slash + 1); + } + else + *poolfs = xstrdup (""); +} +#endif + /* This function never prints trailing slashes (so that its output can be appended a slash unconditionally). */ char * @@ -243,16 +361,26 @@ grub_make_system_path_relative_to_its_root (const char *path) { struct stat st; char *p, *buf, *buf2, *buf3; + char *mnt_point, *poolname = NULL, *poolfs = NULL, *ret; uintptr_t offset = 0; dev_t num; size_t len; /* canonicalize. */ p = canonicalize_file_name (path); - if (p == NULL) grub_util_error ("failed to get canonical path of %s", path); +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ + mnt_point = grub_find_mount_point_from_dir (p); + if (mnt_point) + { + grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs); + free (mnt_point); + } +#endif + len = strlen (p) + 1; buf = xstrdup (p); free (p); @@ -331,7 +459,15 @@ grub_make_system_path_relative_to_its_root (const char *path) len--; } - return buf3; + if (poolfs) + { + ret = xasprintf ("/%s@%s", poolfs, buf3); + free (buf3); + } + else + ret = buf3; + + return ret; } #ifdef HAVE_DEVICE_MAPPER From f7abdefbdd861ec752cf3df6eda42c26c522cdb9 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 1 Aug 2010 23:12:24 +0200 Subject: [PATCH 480/503] 2010-08-01 Robert Millan Make it even harder to use uninitialized `libzfs_handle' (and make the interface a bit simpler). * include/grub/util/misc.h (grub_util_init_libzfs) (libzfs_handle): Remove. (grub_get_libzfs_handle): New prototype. * util/misc.c [HAVE_LIBZFS] (libzfs_handle): Add `static' attribute. (grub_util_init_libzfs): Remove. (grub_get_libzfs_handle): New function. * kern/emu/getroot.c (find_root_device_from_libzfs): Use grub_get_libzfs_handle() to obtain a libzfs handle instead of accessing `libzfs_handle' directly. --- ChangeLog | 18 ++++++++++++++++++ include/grub/util/misc.h | 3 +-- kern/emu/getroot.c | 4 +--- util/misc.c | 14 +++++++------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2956129b3..d4a63c4ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2010-08-01 Robert Millan + + Make it even harder to use uninitialized `libzfs_handle' (and + make the interface a bit simpler). + + * include/grub/util/misc.h (grub_util_init_libzfs) + (libzfs_handle): Remove. + (grub_get_libzfs_handle): New prototype. + + * util/misc.c [HAVE_LIBZFS] (libzfs_handle): Add `static' + attribute. + (grub_util_init_libzfs): Remove. + (grub_get_libzfs_handle): New function. + + * kern/emu/getroot.c (find_root_device_from_libzfs): Use + grub_get_libzfs_handle() to obtain a libzfs handle instead of + accessing `libzfs_handle' directly. + 2010-08-01 Robert Millan * include/grub/emu/misc.h (grub_find_mount_point_from_dir) diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 3614c79c2..7ce3d3291 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -61,7 +61,6 @@ char *canonicalize_file_name (const char *path); void grub_util_init_nls (void); -void grub_util_init_libzfs (void); -extern libzfs_handle_t *libzfs_handle; +libzfs_handle_t *grub_get_libzfs_handle (void); #endif /* ! GRUB_UTIL_MISC_HEADER */ diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 32044536d..ee6e1c7ba 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -197,9 +197,7 @@ find_root_device_from_libzfs (const char *dir) nvlist_t **nvlist_array; unsigned int nvlist_count; - grub_util_init_libzfs (); - - zpool = zpool_open (libzfs_handle, poolname); + zpool = zpool_open (grub_get_libzfs_handle (), poolname); nvlist = zpool_get_config (zpool, NULL); if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0) diff --git a/util/misc.c b/util/misc.c index 2eff256bf..274c182c2 100644 --- a/util/misc.c +++ b/util/misc.c @@ -296,27 +296,27 @@ grub_util_init_nls (void) } #ifdef HAVE_LIBZFS -libzfs_handle_t *libzfs_handle; +static libzfs_handle_t *libzfs_handle; static void fini_libzfs (void) { libzfs_fini (libzfs_handle); } -#endif -void -grub_util_init_libzfs (void) +libzfs_handle_t * +grub_get_libzfs_handle (void) { -#ifdef HAVE_LIBZFS if (! libzfs_handle) { libzfs_handle = libzfs_init (); atexit (fini_libzfs); } -#endif + + return libzfs_handle; } -#endif +#endif /* HAVE_LIBZFS */ +#endif /* GRUB_UTIL */ int grub_dl_ref (grub_dl_t mod) From c7db243b92d530b870bc71ae85e74bb8e3377cf0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 1 Aug 2010 23:21:09 +0200 Subject: [PATCH 481/503] 2010-08-01 Robert Millan * util/grub.d/10_kfreebsd.in: Initialize ${kfreebsd_device} as the kFreeBSD device name, except on ZFS where the filesystem label is used. (kfreebsd_entry): On ZFS root, load `opensolaris.ko', `zfs.ko' and `/boot/zfs/zpool.cache'. Set mountfrom kernel variable using ${kfreebsd_device}. --- ChangeLog | 9 +++++++++ util/grub.d/10_kfreebsd.in | 26 +++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d4a63c4ec..65d6cb667 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-08-01 Robert Millan + + * util/grub.d/10_kfreebsd.in: Initialize ${kfreebsd_device} as the + kFreeBSD device name, except on ZFS where the filesystem label is + used. + (kfreebsd_entry): On ZFS root, load `opensolaris.ko', `zfs.ko' and + `/boot/zfs/zpool.cache'. + Set mountfrom kernel variable using ${kfreebsd_device}. + 2010-08-01 Robert Millan Make it even harder to use uninitialized `libzfs_handle' (and diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index f32da3013..bc5201ab9 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -74,8 +74,27 @@ EOF EOF fi + case "${kfreebsd_fs}" in + zfs) + test -e "${module_dir}/opensolaris.ko" + test -e "${module_dir}/zfs.ko" + test -e "${dirname}/zfs/zpool.cache" + + printf '%s\n' "${prepare_module_dir_cache}" + cat << EOF + kfreebsd_module_elf ${module_dir_rel}/opensolaris.ko + kfreebsd_module_elf ${module_dir_rel}/zfs.ko +EOF + + printf '%s\n' "${prepare_boot_cache}" cat << EOF - set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${GRUB_DEVICE} + kfreebsd_module ${rel_dirname}/zfs/zpool.cache type=/boot/zfs/zpool.cache +EOF + ;; + esac + + cat << EOF + set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${kfreebsd_device} set kFreeBSD.vfs.root.mountfrom.options=rw } EOF @@ -105,6 +124,11 @@ while [ "x$list" != "x" ] ; do *) kfreebsd_fs=${GRUB_FS} ;; esac + case ${GRUB_FS} in + zfs) kfreebsd_device=$(grub-probe -t label --device ${GRUB_DEVICE}) ;; + *) kfreebsd_device=${GRUB_DEVICE} ;; + esac + version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"` alt_version=`echo $version | sed -e "s,\.old$,,g"` From a870a783be2eed43b59c7d537a37484ea05a668c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 2 Aug 2010 09:51:23 -0500 Subject: [PATCH 482/503] * disk/raid.c (insert_array): Select unique numbers for named arrays as well, for use as keys in the disk cache. --- ChangeLog | 5 +++++ disk/raid.c | 29 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65d6cb667..83afffca3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-02 Colin Watson + + * disk/raid.c (insert_array): Select unique numbers for named arrays + as well, for use as keys in the disk cache. + 2010-08-01 Robert Millan * util/grub.d/10_kfreebsd.in: Initialize ${kfreebsd_device} as the diff --git a/disk/raid.c b/disk/raid.c index 7dfd4bd81..51a4b00e2 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -528,25 +528,28 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, grub_memset (&array->device, 0, sizeof (array->device)); grub_memset (&array->start_sector, 0, sizeof (array->start_sector)); - if (array->name) - goto skip_duplicate_check; - /* Check whether we don't have multiple arrays with the same number. */ - for (p = array_list; p != NULL; p = p->next) - { - if (! p->name && p->number == array->number) - break; - } + if (! array->name) + { + for (p = array_list; p != NULL; p = p->next) + { + if (! p->name && p->number == array->number) + break; + } + } - if (p) + if (array->name || p) { - /* The number is already in use, so we need to find a new one. */ - int i = 0; + /* The number is already in use, so we need to find a new one. + (Or, in the case of named arrays, the array doesn't have its + own number, but we need one that doesn't clash for use as a key + in the disk cache. */ + int i = array->name ? 0x40000000 : 0; while (1) { for (p = array_list; p != NULL; p = p->next) { - if (! p->name && p->number == i) + if (p->number == i) break; } @@ -560,7 +563,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, i++; } } - skip_duplicate_check: + /* mdraid 1.x superblocks have only a name stored not a number. Use it directly as GRUB device. */ if (! array->name) From c9f7ff97cfa5107da90469beb01058c952a433e4 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 3 Aug 2010 11:56:36 +0530 Subject: [PATCH 483/503] * script/execute.c (grub_script_execute_cmdline): Check for NULL as command name case. --- ChangeLog | 5 +++++ script/execute.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 83afffca3..d4da9f96c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-03 BVK Chaitanya + + * script/execute.c (grub_script_execute_cmdline): Check for NULL + as command name case. + 2010-08-02 Colin Watson * disk/raid.c (insert_array): Select unique numbers for named arrays diff --git a/script/execute.c b/script/execute.c index 40f161267..c45a15d29 100644 --- a/script/execute.c +++ b/script/execute.c @@ -207,7 +207,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Lookup the command. */ args = grub_script_execute_arglist_to_argv (cmdline->arglist, &argcount); - if (!args) + if (! args || ! args[0]) return grub_errno; cmdname = args[0]; From 9dd6fd50b4e69a3e4b68120ece98e5657a453a5b Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 3 Aug 2010 23:51:48 +0200 Subject: [PATCH 484/503] 2010-08-03 Robert Millan Fix grub-emu build. * include/grub/util/misc.h: Move `' to ... * include/grub/emu/misc.h: ... here. * include/grub/util/misc.h (grub_get_libzfs_handle): Move function ... * include/grub/emu/misc.h (grub_get_libzfs_handle): ... here. * util/misc.c: Remove `'. [HAVE_LIBZFS] (libzfs_handle, fini_libzfs) (grub_get_libzfs_handle): Move to ... * kern/emu/misc.c [HAVE_LIBZFS] (__libzfs_handle, fini_libzfs) (grub_get_libzfs_handle): ... here. --- ChangeLog | 16 ++++++++++++++++ include/grub/emu/misc.h | 3 +++ include/grub/util/misc.h | 3 --- kern/emu/misc.c | 27 ++++++++++++++++++++++++++- util/misc.c | 22 ---------------------- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index d4da9f96c..b3e7bc67f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-08-03 Robert Millan + + Fix grub-emu build. + + * include/grub/util/misc.h: Move `' to ... + * include/grub/emu/misc.h: ... here. + + * include/grub/util/misc.h (grub_get_libzfs_handle): Move function ... + * include/grub/emu/misc.h (grub_get_libzfs_handle): ... here. + + * util/misc.c: Remove `'. + [HAVE_LIBZFS] (libzfs_handle, fini_libzfs) + (grub_get_libzfs_handle): Move to ... + * kern/emu/misc.c [HAVE_LIBZFS] (__libzfs_handle, fini_libzfs) + (grub_get_libzfs_handle): ... here. + 2010-08-03 BVK Chaitanya * script/execute.c (grub_script_execute_cmdline): Check for NULL diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 5047a9406..70cf05e0d 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -21,6 +21,7 @@ #include #include +#include #ifdef __CYGWIN__ # include @@ -75,4 +76,6 @@ extern char * canonicalize_file_name (const char *path); int grub_device_mapper_supported (void); #endif +libzfs_handle_t *grub_get_libzfs_handle (void); + #endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 7ce3d3291..48dfbb868 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -29,7 +29,6 @@ #include #include #include -#include char *grub_util_get_path (const char *dir, const char *file); size_t grub_util_get_fp_size (FILE *fp); @@ -61,6 +60,4 @@ char *canonicalize_file_name (const char *path); void grub_util_init_nls (void); -libzfs_handle_t *grub_get_libzfs_handle (void); - #endif /* ! GRUB_UTIL_MISC_HEADER */ diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 0d71ef3d6..0838dc3c0 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -45,8 +45,11 @@ # include #endif -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +#ifdef HAVE_LIBZFS # include +#endif + +#ifdef HAVE_LIBNVPAIR # include #endif @@ -246,6 +249,28 @@ get_win32_path (const char *path) } #endif +#ifdef HAVE_LIBZFS +static libzfs_handle_t *__libzfs_handle; + +static void +fini_libzfs (void) +{ + libzfs_fini (__libzfs_handle); +} + +libzfs_handle_t * +grub_get_libzfs_handle (void) +{ + if (! __libzfs_handle) + { + __libzfs_handle = libzfs_init (); + atexit (fini_libzfs); + } + + return __libzfs_handle; +} +#endif /* HAVE_LIBZFS */ + #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* Not ZFS-specific in itself, but for now it's only used by ZFS-related code. */ char * diff --git a/util/misc.c b/util/misc.c index 274c182c2..21dd211e1 100644 --- a/util/misc.c +++ b/util/misc.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -295,27 +294,6 @@ grub_util_init_nls (void) #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } -#ifdef HAVE_LIBZFS -static libzfs_handle_t *libzfs_handle; - -static void -fini_libzfs (void) -{ - libzfs_fini (libzfs_handle); -} - -libzfs_handle_t * -grub_get_libzfs_handle (void) -{ - if (! libzfs_handle) - { - libzfs_handle = libzfs_init (); - atexit (fini_libzfs); - } - - return libzfs_handle; -} -#endif /* HAVE_LIBZFS */ #endif /* GRUB_UTIL */ int From 62858144fe582fe4a908d277842cd50e00eba634 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 4 Aug 2010 00:15:29 +0200 Subject: [PATCH 485/503] 2010-08-04 Robert Millan Support OpenSolaris in ZFS device resolution. * configure.ac: Check for getmntany(). * kern/emu/misc.c [HAVE_GETMNTANY]: Include `'. [HAVE_GETMNTANY] (grub_find_zpool_from_mount_point): Add OpenSolaris support. --- ChangeLog | 9 +++++++++ configure.ac | 2 +- kern/emu/misc.c | 24 +++++++++++++++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3e7bc67f..958c55c79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-08-04 Robert Millan + + Support OpenSolaris in ZFS device resolution. + + * configure.ac: Check for getmntany(). + * kern/emu/misc.c [HAVE_GETMNTANY]: Include `'. + [HAVE_GETMNTANY] (grub_find_zpool_from_mount_point): Add OpenSolaris + support. + 2010-08-03 Robert Millan Fix grub-emu build. diff --git a/configure.ac b/configure.ac index 6169a2fb5..41072eb4f 100644 --- a/configure.ac +++ b/configure.ac @@ -247,7 +247,7 @@ else fi # Check for functions and headers. -AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat) +AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat getmntany) AC_CHECK_HEADERS(libzfs.h libnvpair.h) # For opendisk() and getrawpartition() on NetBSD. diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 0838dc3c0..5a148c708 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -32,6 +32,10 @@ #include #endif +#ifdef HAVE_GETMNTANY +# include +#endif + #include #include #include @@ -340,7 +344,7 @@ grub_find_zpool_from_mount_point (const char *mnt_point, char **poolname, char * *poolname = *poolfs = NULL; -#ifdef HAVE_GETFSSTAT +#if defined(HAVE_GETFSSTAT) /* FreeBSD and GNU/kFreeBSD */ { int mnt_count = getfsstat (NULL, 0, MNT_WAIT); if (mnt_count == -1) @@ -363,6 +367,24 @@ grub_find_zpool_from_mount_point (const char *mnt_point, char **poolname, char * free (mnt); } +#elif defined(HAVE_GETMNTANY) /* OpenSolaris */ + { + FILE *mnttab = fopen ("/etc/mnttab", "r"); + struct mnttab mp; + struct mnttab mpref = + { + .mnt_special = NULL, + .mnt_mountp = mnt_point, + .mnt_fstype = "zfs", + .mnt_mntopts = NULL, + .mnt_time = NULL, + }; + + if (getmntany (mnttab, &mp, &mpref) == 0) + *poolname = xstrdup (mp.mnt_special); + + fclose (mnttab); + } #endif if (! *poolname) From 0de22aa997fa162d626ed1c4f472bad4915e8e7f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 4 Aug 2010 13:29:13 +0200 Subject: [PATCH 486/503] 2010-08-04 Robert Millan * include/grub/emu/misc.h (grub_find_mount_point_from_dir) (grub_find_zpool_from_mount_point): Merge into ... (grub_find_zpool_from_dir): ... this. * kern/emu/misc.c: Likewise. * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Replace grub_find_mount_point_from_dir() / grub_find_zpool_from_mount_point() with grub_find_zpool_from_dir(). * kern/emu/getroot.c (find_root_device_from_libzfs): Likewise. --- ChangeLog | 13 +++++++++++++ include/grub/emu/misc.h | 6 ++---- kern/emu/getroot.c | 9 ++------- kern/emu/misc.c | 21 ++++++++------------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 958c55c79..daa85e4a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-08-04 Robert Millan + + * include/grub/emu/misc.h (grub_find_mount_point_from_dir) + (grub_find_zpool_from_mount_point): Merge into ... + (grub_find_zpool_from_dir): ... this. + * kern/emu/misc.c: Likewise. + + * kern/emu/misc.c + (grub_make_system_path_relative_to_its_root): Replace + grub_find_mount_point_from_dir() / grub_find_zpool_from_mount_point() + with grub_find_zpool_from_dir(). + * kern/emu/getroot.c (find_root_device_from_libzfs): Likewise. + 2010-08-04 Robert Millan Support OpenSolaris in ZFS device resolution. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 70cf05e0d..ebb81a37f 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -45,10 +45,8 @@ extern const char *program_name; void grub_init_all (void); void grub_fini_all (void); -char *grub_find_mount_point_from_dir (const char *dir) - __attribute__ ((warn_unused_result)); -void grub_find_zpool_from_mount_point (const char *mnt_point, - char **poolname, char **poolfs); +void grub_find_zpool_from_dir (const char *dir, + char **poolname, char **poolfs); char *grub_make_system_path_relative_to_its_root (const char *path) __attribute__ ((warn_unused_result)); diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index ee6e1c7ba..321b33bb3 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -181,15 +181,10 @@ find_root_device_from_libzfs (const char *dir) char *device; char *poolname; char *poolfs; - char *mnt_point; - mnt_point = grub_find_mount_point_from_dir (dir); - grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs); + grub_find_zpool_from_dir (dir, &poolname, &poolfs); if (! poolname) - { - free (mnt_point); - return NULL; - } + return NULL; { zpool_handle_t *zpool; diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 5a148c708..de22e3bff 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -277,8 +277,8 @@ grub_get_libzfs_handle (void) #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* Not ZFS-specific in itself, but for now it's only used by ZFS-related code. */ -char * -grub_find_mount_point_from_dir (const char *dir) +static char * +find_mount_point_from_dir (const char *dir) { struct stat st; typeof (st.st_dev) fs; @@ -332,18 +332,18 @@ grub_find_mount_point_from_dir (const char *dir) } } } -#endif - -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* ZFS has similar problems to those of btrfs (see above). */ void -grub_find_zpool_from_mount_point (const char *mnt_point, char **poolname, char **poolfs) +grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) { char *slash; + char *mnt_point; *poolname = *poolfs = NULL; + mnt_point = find_mount_point_from_dir (dir); + #if defined(HAVE_GETFSSTAT) /* FreeBSD and GNU/kFreeBSD */ { int mnt_count = getfsstat (NULL, 0, MNT_WAIT); @@ -408,7 +408,7 @@ grub_make_system_path_relative_to_its_root (const char *path) { struct stat st; char *p, *buf, *buf2, *buf3; - char *mnt_point, *poolname = NULL, *poolfs = NULL, *ret; + char *poolname = NULL, *poolfs = NULL, *ret; uintptr_t offset = 0; dev_t num; size_t len; @@ -420,12 +420,7 @@ grub_make_system_path_relative_to_its_root (const char *path) #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ - mnt_point = grub_find_mount_point_from_dir (p); - if (mnt_point) - { - grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs); - free (mnt_point); - } + grub_find_zpool_from_dir (p, &poolname, &poolfs); #endif len = strlen (p) + 1; From d3dd9e80f63b76ad061b02b1c2aac4ed1af67662 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 4 Aug 2010 14:45:58 +0200 Subject: [PATCH 487/503] 2010-08-04 Robert Millan * configure.ac: Remove checks for getfsstat() and getmntany(). Add checks for `' and `'. * kern/emu/misc.c [HAVE_GETMNTANY]: Remove `'. [HAVE_SYS_PARAM_H]: Include `'. [HAVE_SYS_MOUNT_H]: Include `'. [HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_mount_point_from_dir): Remove function. (grub_find_zpool_from_dir): Use statfs() instead of indirect matching via find_mount_point_from_dir() and getfsstat() / getmntany(). --- ChangeLog | 12 +++++ configure.ac | 4 +- kern/emu/misc.c | 118 ++++-------------------------------------------- 3 files changed, 23 insertions(+), 111 deletions(-) diff --git a/ChangeLog b/ChangeLog index daa85e4a3..417cc4a6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-08-04 Robert Millan + + * configure.ac: Remove checks for getfsstat() and getmntany(). + Add checks for `' and `'. + * kern/emu/misc.c [HAVE_GETMNTANY]: Remove `'. + [HAVE_SYS_PARAM_H]: Include `'. + [HAVE_SYS_MOUNT_H]: Include `'. + [HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_mount_point_from_dir): Remove + function. + (grub_find_zpool_from_dir): Use statfs() instead of indirect matching + via find_mount_point_from_dir() and getfsstat() / getmntany(). + 2010-08-04 Robert Millan * include/grub/emu/misc.h (grub_find_mount_point_from_dir) diff --git a/configure.ac b/configure.ac index 41072eb4f..19d782609 100644 --- a/configure.ac +++ b/configure.ac @@ -247,8 +247,8 @@ else fi # Check for functions and headers. -AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat getmntany) -AC_CHECK_HEADERS(libzfs.h libnvpair.h) +AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf) +AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.h) # For opendisk() and getrawpartition() on NetBSD. # Used in util/deviceiter.c and in util/hostdisk.c. diff --git a/kern/emu/misc.c b/kern/emu/misc.c index de22e3bff..b9afa167f 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -32,10 +32,6 @@ #include #endif -#ifdef HAVE_GETMNTANY -# include -#endif - #include #include #include @@ -57,7 +53,11 @@ # include #endif -#ifdef HAVE_GETFSSTAT +#ifdef HAVE_SYS_PARAM_H +# include +#endif + +#ifdef HAVE_SYS_MOUNT_H # include #endif @@ -276,120 +276,20 @@ grub_get_libzfs_handle (void) #endif /* HAVE_LIBZFS */ #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) -/* Not ZFS-specific in itself, but for now it's only used by ZFS-related code. */ -static char * -find_mount_point_from_dir (const char *dir) -{ - struct stat st; - typeof (st.st_dev) fs; - char *prev, *next, *slash, *statdir; - - if (stat (dir, &st) == -1) - error (1, errno, "stat (%s)", dir); - - fs = st.st_dev; - - prev = xstrdup (dir); - - while (1) - { - /* Remove last slash. */ - next = xstrdup (prev); - slash = strrchr (next, '/'); - if (! slash) - { - free (next); - free (prev); - return NULL; - } - *slash = '\0'; - - /* A next empty string counts as /. */ - if (next[0] == '\0') - statdir = "/"; - else - statdir = next; - - if (stat (statdir, &st) == -1) - error (1, errno, "stat (%s)", next); - - if (st.st_dev != fs) - { - /* Found mount point. */ - free (next); - return prev; - } - - free (prev); - prev = next; - - /* We've already seen an empty string, which means we - reached /. Nothing left to do. */ - if (prev[0] == '\0') - { - free (prev); - return xstrdup ("/"); - } - } -} - /* ZFS has similar problems to those of btrfs (see above). */ void grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) { + struct statfs mnt; char *slash; - char *mnt_point; *poolname = *poolfs = NULL; - mnt_point = find_mount_point_from_dir (dir); - -#if defined(HAVE_GETFSSTAT) /* FreeBSD and GNU/kFreeBSD */ - { - int mnt_count = getfsstat (NULL, 0, MNT_WAIT); - if (mnt_count == -1) - error (1, errno, "getfsstat"); - - struct statfs *mnt = xmalloc (mnt_count * sizeof (*mnt)); - - mnt_count = getfsstat (mnt, mnt_count * sizeof (*mnt), MNT_WAIT); - if (mnt_count == -1) - error (1, errno, "getfsstat"); - - unsigned int i; - for (i = 0; i < (unsigned) mnt_count; i++) - if (!strcmp (mnt[i].f_fstypename, "zfs") - && !strcmp (mnt[i].f_mntonname, mnt_point)) - { - *poolname = xstrdup (mnt[i].f_mntfromname); - break; - } - - free (mnt); - } -#elif defined(HAVE_GETMNTANY) /* OpenSolaris */ - { - FILE *mnttab = fopen ("/etc/mnttab", "r"); - struct mnttab mp; - struct mnttab mpref = - { - .mnt_special = NULL, - .mnt_mountp = mnt_point, - .mnt_fstype = "zfs", - .mnt_mntopts = NULL, - .mnt_time = NULL, - }; - - if (getmntany (mnttab, &mp, &mpref) == 0) - *poolname = xstrdup (mp.mnt_special); - - fclose (mnttab); - } -#endif - - if (! *poolname) + if (statfs (dir, &mnt) != 0) return; + *poolname = xstrdup (mnt.f_mntfromname); + slash = strchr (*poolname, '/'); if (slash) { From 55dd292477766438556c92fd614cd437c90971f7 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 8 Aug 2010 15:45:33 +0200 Subject: [PATCH 488/503] 2010-08-08 Robert Millan Fix grub-probe invocation. * util/grub.d/10_kfreebsd.in: s/label/fs_label/g. --- ChangeLog | 6 ++++++ util/grub.d/10_kfreebsd.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 417cc4a6a..65120fc25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-08-08 Robert Millan + + Fix grub-probe invocation. + + * util/grub.d/10_kfreebsd.in: s/label/fs_label/g. + 2010-08-04 Robert Millan * configure.ac: Remove checks for getfsstat() and getmntany(). diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index bc5201ab9..29737f990 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -125,7 +125,7 @@ while [ "x$list" != "x" ] ; do esac case ${GRUB_FS} in - zfs) kfreebsd_device=$(grub-probe -t label --device ${GRUB_DEVICE}) ;; + zfs) kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE}) ;; *) kfreebsd_device=${GRUB_DEVICE} ;; esac From 0d8286f32816067967817eceade37e5924b16c5d Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 8 Aug 2010 16:27:58 +0200 Subject: [PATCH 489/503] 2010-08-08 Robert Millan * util/grub.d/10_kfreebsd.in: When files required for ZFS do not exist, issue a proper error message (rely on `ls' for translated strings). --- ChangeLog | 6 ++++++ util/grub.d/10_kfreebsd.in | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65120fc25..df8d040fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-08-08 Robert Millan + + * util/grub.d/10_kfreebsd.in: When files required for ZFS do not + exist, issue a proper error message (rely on `ls' for translated + strings). + 2010-08-08 Robert Millan Fix grub-probe invocation. diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 29737f990..3a42de529 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -76,9 +76,10 @@ EOF case "${kfreebsd_fs}" in zfs) - test -e "${module_dir}/opensolaris.ko" - test -e "${module_dir}/zfs.ko" - test -e "${dirname}/zfs/zpool.cache" + for i in "${module_dir}/opensolaris.ko" "${module_dir}/zfs.ko" \ + "${dirname}/zfs/zpool.cache" ; do + ls "$i" > /dev/null + done printf '%s\n' "${prepare_module_dir_cache}" cat << EOF From 7117542069db6660f2d40d5f79a51ab2db0fa89e Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 8 Aug 2010 22:47:32 +0200 Subject: [PATCH 490/503] 2010-08-08 Robert Millan * util/grub-fstest.c (read_file, cmd_cmp): Improve error message. --- ChangeLog | 4 ++++ util/grub-fstest.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index df8d040fd..4d7361472 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-08 Robert Millan + + * util/grub-fstest.c (read_file, cmd_cmp): Improve error message. + 2010-08-08 Robert Millan * util/grub.d/10_kfreebsd.in: When files required for ZFS do not diff --git a/util/grub-fstest.c b/util/grub-fstest.c index f1692c0a3..2c80b964c 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -157,7 +157,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len); if (sz < 0) { - grub_util_error ("read error at offset %llu", ofs); + grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg); break; } @@ -211,7 +211,7 @@ cmd_cmp (char *src, char *dest) { if ((int) fread (buf_1, 1, len, ff) != len) { - grub_util_error ("read error at offset %llu", ofs); + grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg); return 1; } From 346c207240bf1a21ba212601b3a3647e2e4a17d1 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 9 Aug 2010 00:11:19 +0200 Subject: [PATCH 491/503] 2010-08-08 Robert Millan Fix path generation for sub-filesystems in ZFS. * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Add missing slash. --- ChangeLog | 7 +++++++ kern/emu/misc.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4d7361472..3619b00fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-08-08 Robert Millan + + Fix path generation for sub-filesystems in ZFS. + + * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Add + missing slash. + 2010-08-08 Robert Millan * util/grub-fstest.c (read_file, cmd_cmp): Improve error message. diff --git a/kern/emu/misc.c b/kern/emu/misc.c index b9afa167f..d1a92de30 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -403,7 +403,7 @@ grub_make_system_path_relative_to_its_root (const char *path) if (poolfs) { - ret = xasprintf ("/%s@%s", poolfs, buf3); + ret = xasprintf ("/%s/@%s", poolfs, buf3); free (buf3); } else From 07f360e92dda7197912b1ba4340e3cdbadf7d8af Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 9 Aug 2010 17:44:24 +0200 Subject: [PATCH 492/503] 2010-08-09 Robert Millan * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Filter out unused variables on non-ZFS build. --- ChangeLog | 5 +++++ kern/emu/misc.c | 14 +++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3619b00fa..b0cbd54a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-09 Robert Millan + + * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Filter + out unused variables on non-ZFS build. + 2010-08-08 Robert Millan Fix path generation for sub-filesystems in ZFS. diff --git a/kern/emu/misc.c b/kern/emu/misc.c index d1a92de30..760471ebb 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -307,12 +307,15 @@ char * grub_make_system_path_relative_to_its_root (const char *path) { struct stat st; - char *p, *buf, *buf2, *buf3; - char *poolname = NULL, *poolfs = NULL, *ret; + char *p, *buf, *buf2, *buf3, *ret; uintptr_t offset = 0; dev_t num; size_t len; +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + char *poolfs = NULL; +#endif + /* canonicalize. */ p = canonicalize_file_name (path); if (p == NULL) @@ -320,7 +323,10 @@ grub_make_system_path_relative_to_its_root (const char *path) #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ - grub_find_zpool_from_dir (p, &poolname, &poolfs); + { + char *dummy; + grub_find_zpool_from_dir (p, &dummy, &poolfs); + } #endif len = strlen (p) + 1; @@ -401,12 +407,14 @@ grub_make_system_path_relative_to_its_root (const char *path) len--; } +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) if (poolfs) { ret = xasprintf ("/%s/@%s", poolfs, buf3); free (buf3); } else +#endif ret = buf3; return ret; From cf0c775ed41b7ee256ef496588f5ee2871d63dac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 10 Aug 2010 13:43:43 +0200 Subject: [PATCH 493/503] * include/grub/vga.h (grub_vga_gr_write): Add GRUB_MACHINE_PCI_IO_BASE. (grub_vga_gr_read): Likewise. (grub_vga_cr_write): Likewise. (grub_vga_cr_read): Likewise. (grub_vga_sr_write): Likewise. (grub_vga_sr_read): Likewise. (grub_vga_palette_read): Likewise. (grub_vga_palette_write): Likewise. * video/sm712.c (GRUB_SM712_REG_BASE): New definition. (grub_sm712_sr_read): New function. (grub_video_sm712_setup): Use grub_vga_sr_write and grub_sm712_sr_read. * video/sm712_init.c (sm712_init): Substract GRUB_MACHINE_PCI_IO_BASE. --- ChangeLog | 15 + include/grub/vga.h | 41 +- video/sm712.c | 35 +- video/sm712_init.c | 1068 ++++++++++++++++++++++---------------------- 4 files changed, 589 insertions(+), 570 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0cbd54a0..0829eb83e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-08-10 Vladimir Serbinenko + + * include/grub/vga.h (grub_vga_gr_write): Add GRUB_MACHINE_PCI_IO_BASE. + (grub_vga_gr_read): Likewise. + (grub_vga_cr_write): Likewise. + (grub_vga_cr_read): Likewise. + (grub_vga_sr_write): Likewise. + (grub_vga_sr_read): Likewise. + (grub_vga_palette_read): Likewise. + (grub_vga_palette_write): Likewise. + * video/sm712.c (GRUB_SM712_REG_BASE): New definition. + (grub_sm712_sr_read): New function. + (grub_video_sm712_setup): Use grub_vga_sr_write and grub_sm712_sr_read. + * video/sm712_init.c (sm712_init): Substract GRUB_MACHINE_PCI_IO_BASE. + 2010-08-09 Robert Millan * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Filter diff --git a/include/grub/vga.h b/include/grub/vga.h index d4a1523a7..0ca56e37f 100644 --- a/include/grub/vga.h +++ b/include/grub/vga.h @@ -132,64 +132,63 @@ enum static inline void grub_vga_gr_write (grub_uint8_t val, grub_uint8_t addr) { - grub_outb (addr, GRUB_VGA_IO_GR_INDEX); - grub_outb (val, GRUB_VGA_IO_GR_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_INDEX); + grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_DATA); } static inline grub_uint8_t grub_vga_gr_read (grub_uint8_t addr) { - grub_outb (addr, GRUB_VGA_IO_GR_INDEX); - return grub_inb (GRUB_VGA_IO_GR_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_INDEX); + return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_DATA); } static inline void grub_vga_cr_write (grub_uint8_t val, grub_uint8_t addr) { - grub_outb (addr, GRUB_VGA_IO_CR_INDEX); - grub_outb (val, GRUB_VGA_IO_CR_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_INDEX); + grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_DATA); } static inline grub_uint8_t grub_vga_cr_read (grub_uint8_t addr) { - grub_outb (addr, GRUB_VGA_IO_CR_INDEX); - return grub_inb (GRUB_VGA_IO_CR_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_INDEX); + return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_DATA); } static inline void grub_vga_sr_write (grub_uint8_t val, grub_uint8_t addr) { - grub_outb (addr, GRUB_VGA_IO_SR_INDEX); - grub_outb (val, GRUB_VGA_IO_SR_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX); + grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA); } static inline grub_uint8_t grub_vga_sr_read (grub_uint8_t addr) { - grub_outb (addr, GRUB_VGA_IO_SR_INDEX); - return grub_inb (GRUB_VGA_IO_SR_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX); + return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA); } static inline void grub_vga_palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g, grub_uint8_t *b) { - grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX); - *r = grub_inb (GRUB_VGA_IO_PALLETTE_DATA); - *g = grub_inb (GRUB_VGA_IO_PALLETTE_DATA); - *b = grub_inb (GRUB_VGA_IO_PALLETTE_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_READ_INDEX); + *r = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); + *g = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); + *b = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); } static inline void grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, grub_uint8_t b) { - grub_outb (addr, GRUB_VGA_IO_PALLETTE_WRITE_INDEX); - grub_outb (r, GRUB_VGA_IO_PALLETTE_DATA); - grub_outb (g, GRUB_VGA_IO_PALLETTE_DATA); - grub_outb (b, GRUB_VGA_IO_PALLETTE_DATA); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_WRITE_INDEX); + grub_outb (r, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); + grub_outb (g, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); + grub_outb (b, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); } - #endif diff --git a/video/sm712.c b/video/sm712.c index a58032c42..db7494a62 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -26,10 +26,12 @@ #include #include #include +#include #include "sm712_init.c" #define GRUB_SM712_TOTAL_MEMORY_SPACE 0x700400 +#define GRUB_SM712_REG_BASE 0x700000 static struct { @@ -61,6 +63,15 @@ grub_video_sm712_video_fini (void) return grub_video_fb_fini (); } +static inline grub_uint8_t +grub_sm712_sr_read (grub_uint8_t addr) +{ + *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE + + GRUB_VGA_IO_SR_INDEX) = addr; + return *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE + + GRUB_VGA_IO_SR_DATA); +} + static grub_err_t grub_video_sm712_setup (unsigned int width, unsigned int height, unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) @@ -148,8 +159,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, framebuffer.mapped = 1; /* Initialise SM712. */ - grub_outb (0x18, GRUB_MACHINE_PCI_IO_BASE + 0x3c4); - grub_outb (0x11, GRUB_MACHINE_PCI_IO_BASE + 0x3c5); + grub_vga_sr_write (0x11, 0x18); /* Prevent garbage from appearing on the screen. */ grub_memset (framebuffer.ptr, 0, @@ -159,26 +169,27 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, switch (sm712_init[i].directive) { case 1: - *(volatile grub_uint8_t *) ((char *) framebuffer.ptr + *(volatile grub_uint8_t *) ((char *) framebuffer.ptr + + GRUB_SM712_REG_BASE + sm712_init[i].addr) = sm712_init[i].val; break; case -1: { grub_uint8_t val = *(volatile grub_uint8_t *) - ((char *) framebuffer.ptr + sm712_init[i].addr); + ((char *) framebuffer.ptr + GRUB_SM712_REG_BASE + + sm712_init[i].addr); (void) val; } break; - case 2: - *(volatile grub_uint16_t *) ((char *) framebuffer.ptr - + sm712_init[i].addr) = sm712_init[i].val; - break; - case 4: - *(volatile grub_uint32_t *) ((char *) framebuffer.ptr - + sm712_init[i].addr) = sm712_init[i].val; - break; } + *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c00c) = 0; + *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c040) = 0; + *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c000) = 0x20000; + *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c010) = 0x1020100; + + (void) grub_sm712_sr_read (0x16); + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) diff --git a/video/sm712_init.c b/video/sm712_init.c index 02c64c453..58dbbbbf9 100644 --- a/video/sm712_init.c +++ b/video/sm712_init.c @@ -6,541 +6,535 @@ static struct grub_uint32_t val; } sm712_init[] = { - {1, 0x7003c4, 0x21}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x62}, - {1, 0x7003c5, 0x7a}, - {1, 0x7003c4, 0x6a}, - {1, 0x7003c5, 0x16}, - {1, 0x7003c4, 0x6b}, - {1, 0x7003c5, 0x2}, - {1, 0x7003c6, 0x0}, - {1, 0x7003c4, 0x0}, - {1, 0x7003c5, 0x1}, - {1, 0x7003c2, 0xeb}, - {1, 0x7003c4, 0x0}, - {1, 0x7003c5, 0x3}, - {1, 0x7003c4, 0x1}, - {1, 0x7003c5, 0x1}, - {1, 0x7003c4, 0x2}, - {1, 0x7003c5, 0xf}, - {1, 0x7003c4, 0x3}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x4}, - {1, 0x7003c5, 0xe}, - {1, 0x7003c4, 0x10}, - {1, 0x7003c5, 0xc8}, - {1, 0x7003c4, 0x11}, - {1, 0x7003c5, 0x40}, - {1, 0x7003c4, 0x12}, - {1, 0x7003c5, 0x14}, - {1, 0x7003c4, 0x13}, - {1, 0x7003c5, 0x60}, - {1, 0x7003c4, 0x14}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x15}, - {1, 0x7003c5, 0xa}, - {1, 0x7003c4, 0x16}, - {1, 0x7003c5, 0x92}, - {1, 0x7003c4, 0x17}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x18}, - {1, 0x7003c5, 0x51}, - {1, 0x7003c4, 0x19}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x1a}, - {1, 0x7003c5, 0x1}, - {1, 0x7003c4, 0x1b}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x1c}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x1d}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x1e}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x1f}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x20}, - {1, 0x7003c5, 0xc4}, - {1, 0x7003c4, 0x21}, - {1, 0x7003c5, 0x30}, - {1, 0x7003c4, 0x22}, - {1, 0x7003c5, 0x2}, - {1, 0x7003c4, 0x23}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x24}, - {1, 0x7003c5, 0x1}, - {1, 0x7003c4, 0x30}, - {1, 0x7003c5, 0x28}, - {1, 0x7003c4, 0x31}, - {1, 0x7003c5, 0x3}, - {1, 0x7003c4, 0x32}, - {1, 0x7003c5, 0x24}, - {1, 0x7003c4, 0x33}, - {1, 0x7003c5, 0x9}, - {1, 0x7003c4, 0x34}, - {1, 0x7003c5, 0xc0}, - {1, 0x7003c4, 0x35}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x36}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x37}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x38}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x39}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x3a}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x3b}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x3c}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x3d}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x3e}, - {1, 0x7003c5, 0x3}, - {1, 0x7003c4, 0x3f}, - {1, 0x7003c5, 0xff}, - {1, 0x7003c4, 0x40}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x41}, - {1, 0x7003c5, 0xfc}, - {1, 0x7003c4, 0x42}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x43}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x44}, - {1, 0x7003c5, 0x20}, - {1, 0x7003c4, 0x45}, - {1, 0x7003c5, 0x18}, - {1, 0x7003c4, 0x46}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x47}, - {1, 0x7003c5, 0xfc}, - {1, 0x7003c4, 0x48}, - {1, 0x7003c5, 0x20}, - {1, 0x7003c4, 0x49}, - {1, 0x7003c5, 0xc}, - {1, 0x7003c4, 0x4a}, - {1, 0x7003c5, 0x44}, - {1, 0x7003c4, 0x4b}, - {1, 0x7003c5, 0x20}, - {1, 0x7003c4, 0x4c}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x4d}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x4e}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x4f}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x50}, - {1, 0x7003c5, 0x6}, - {1, 0x7003c4, 0x51}, - {1, 0x7003c5, 0x68}, - {1, 0x7003c4, 0x52}, - {1, 0x7003c5, 0xa7}, - {1, 0x7003c4, 0x53}, - {1, 0x7003c5, 0x7f}, - {1, 0x7003c4, 0x54}, - {1, 0x7003c5, 0x83}, - {1, 0x7003c4, 0x55}, - {1, 0x7003c5, 0x24}, - {1, 0x7003c4, 0x56}, - {1, 0x7003c5, 0xff}, - {1, 0x7003c4, 0x57}, - {1, 0x7003c5, 0x3}, - {1, 0x7003c4, 0x58}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x59}, - {1, 0x7003c5, 0x60}, - {1, 0x7003c4, 0x5a}, - {1, 0x7003c5, 0x59}, - {1, 0x7003c4, 0x5b}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x5c}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x5d}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x5e}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x5f}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x60}, - {1, 0x7003c5, 0x1}, - {1, 0x7003c4, 0x61}, - {1, 0x7003c5, 0x80}, - {1, 0x7003c4, 0x63}, - {1, 0x7003c5, 0x1a}, - {1, 0x7003c4, 0x64}, - {1, 0x7003c5, 0x1a}, - {1, 0x7003c4, 0x65}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x66}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x67}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x68}, - {1, 0x7003c5, 0x50}, - {1, 0x7003c4, 0x69}, - {1, 0x7003c5, 0x3}, - {1, 0x7003c4, 0x6c}, - {1, 0x7003c5, 0x52}, - {1, 0x7003c4, 0x6d}, - {1, 0x7003c5, 0x89}, - {1, 0x7003c4, 0x6e}, - {1, 0x7003c5, 0x9}, - {1, 0x7003c4, 0x6f}, - {1, 0x7003c5, 0x2}, - {1, 0x7003c4, 0x70}, - {1, 0x7003c5, 0x4}, - {1, 0x7003c4, 0x71}, - {1, 0x7003c5, 0x45}, - {1, 0x7003c4, 0x72}, - {1, 0x7003c5, 0x30}, - {1, 0x7003c4, 0x73}, - {1, 0x7003c5, 0x30}, - {1, 0x7003c4, 0x74}, - {1, 0x7003c5, 0x40}, - {1, 0x7003c4, 0x75}, - {1, 0x7003c5, 0x20}, - {1, 0x7003c4, 0x80}, - {1, 0x7003c5, 0xff}, - {1, 0x7003c4, 0x81}, - {1, 0x7003c5, 0x7}, - {1, 0x7003c4, 0x82}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x83}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x84}, - {1, 0x7003c5, 0x8}, - {1, 0x7003c4, 0x85}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x86}, - {1, 0x7003c5, 0x42}, - {1, 0x7003c4, 0x87}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x88}, - {1, 0x7003c5, 0x59}, - {1, 0x7003c4, 0x89}, - {1, 0x7003c5, 0x2}, - {1, 0x7003c4, 0x8a}, - {1, 0x7003c5, 0x44}, - {1, 0x7003c4, 0x8b}, - {1, 0x7003c5, 0x2}, - {1, 0x7003c4, 0x8c}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x8d}, - {1, 0x7003c5, 0xff}, - {1, 0x7003c4, 0x8e}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x8f}, - {1, 0x7003c5, 0x3a}, - {1, 0x7003c4, 0x90}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x91}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x92}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0x93}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0xa0}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0xa1}, - {1, 0x7003c5, 0x10}, - {1, 0x7003c4, 0xa2}, - {1, 0x7003c5, 0x8}, - {1, 0x7003c4, 0xa3}, - {1, 0x7003c5, 0x0}, - {1, 0x7003c4, 0xa4}, - {1, 0x7003c5, 0x2}, - {1, 0x7003c4, 0xa5}, - {1, 0x7003c5, 0xed}, - {1, 0x7003c4, 0xa6}, - {1, 0x7003c5, 0xed}, - {1, 0x7003c4, 0xa7}, - {1, 0x7003c5, 0xed}, - {1, 0x7003c4, 0xa8}, - {1, 0x7003c5, 0x7b}, - {1, 0x7003c4, 0xa9}, - {1, 0x7003c5, 0xfb}, - {1, 0x7003c4, 0xaa}, - {1, 0x7003c5, 0xff}, - {1, 0x7003c4, 0xab}, - {1, 0x7003c5, 0xff}, - {1, 0x7003c4, 0xac}, - {1, 0x7003c5, 0x97}, - {1, 0x7003c4, 0xad}, - {1, 0x7003c5, 0xef}, - {1, 0x7003c4, 0xae}, - {1, 0x7003c5, 0xbf}, - {1, 0x7003c4, 0xaf}, - {1, 0x7003c5, 0xdf}, - {1, 0x7003ce, 0x0}, - {1, 0x7003cf, 0x0}, - {1, 0x7003ce, 0x1}, - {1, 0x7003cf, 0x0}, - {1, 0x7003ce, 0x2}, - {1, 0x7003cf, 0x0}, - {1, 0x7003ce, 0x3}, - {1, 0x7003cf, 0x0}, - {1, 0x7003ce, 0x4}, - {1, 0x7003cf, 0x0}, - {1, 0x7003ce, 0x5}, - {1, 0x7003cf, 0x40}, - {1, 0x7003ce, 0x6}, - {1, 0x7003cf, 0x5}, - {1, 0x7003ce, 0x7}, - {1, 0x7003cf, 0xf}, - {1, 0x7003ce, 0x8}, - {1, 0x7003cf, 0xff}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x0}, - {-1, 0x7003c1, 0x3e}, - {1, 0x7003c0, 0x0}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x1}, - {-1, 0x7003c1, 0x3b}, - {1, 0x7003c0, 0x1}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x2}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0x2}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x3}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0x3}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x4}, - {-1, 0x7003c1, 0x3b}, - {1, 0x7003c0, 0x4}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x5}, - {-1, 0x7003c1, 0x2f}, - {1, 0x7003c0, 0x5}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x6}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0x6}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x7}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0x7}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x8}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0x8}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x9}, - {-1, 0x7003c1, 0x3d}, - {1, 0x7003c0, 0x9}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0xa}, - {-1, 0x7003c1, 0x1f}, - {1, 0x7003c0, 0xa}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0xb}, - {-1, 0x7003c1, 0x1f}, - {1, 0x7003c0, 0xb}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0xc}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0xc}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0xd}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0xd}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0xe}, - {-1, 0x7003c1, 0x3f}, - {1, 0x7003c0, 0xe}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0xf}, - {-1, 0x7003c1, 0x2e}, - {1, 0x7003c0, 0xf}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x10}, - {-1, 0x7003c1, 0x0}, - {1, 0x7003c0, 0x41}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x11}, - {-1, 0x7003c1, 0x0}, - {1, 0x7003c0, 0x0}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x12}, - {-1, 0x7003c1, 0x0}, - {1, 0x7003c0, 0xf}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x13}, - {-1, 0x7003c1, 0x0}, - {1, 0x7003c0, 0x0}, - {-1, 0x7003da, 0x5}, - {1, 0x7003c0, 0x14}, - {-1, 0x7003c1, 0x0}, - {1, 0x7003c0, 0x0}, - {1, 0x7003d4, 0x0}, - {1, 0x7003d5, 0xa3}, - {1, 0x7003d4, 0x1}, - {1, 0x7003d5, 0x7f}, - {1, 0x7003d4, 0x2}, - {1, 0x7003d5, 0x7f}, - {1, 0x7003d4, 0x3}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x4}, - {1, 0x7003d5, 0x85}, - {1, 0x7003d4, 0x5}, - {1, 0x7003d5, 0x16}, - {1, 0x7003d4, 0x6}, - {1, 0x7003d5, 0x24}, - {1, 0x7003d4, 0x7}, - {1, 0x7003d5, 0xf5}, - {1, 0x7003d4, 0x8}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x9}, - {1, 0x7003d5, 0x60}, - {1, 0x7003d4, 0xa}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0xb}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0xc}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0xd}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0xe}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0xf}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x10}, - {1, 0x7003d5, 0x3}, - {1, 0x7003d4, 0x11}, - {1, 0x7003d5, 0x9}, - {1, 0x7003d4, 0x12}, - {1, 0x7003d5, 0xff}, - {1, 0x7003d4, 0x13}, - {1, 0x7003d5, 0x80}, - {1, 0x7003d4, 0x14}, - {1, 0x7003d5, 0x40}, - {1, 0x7003d4, 0x15}, - {1, 0x7003d5, 0xff}, - {1, 0x7003d4, 0x16}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x17}, - {1, 0x7003d5, 0xe3}, - {1, 0x7003d4, 0x18}, - {1, 0x7003d5, 0xff}, - {1, 0x7003d4, 0x30}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x31}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x32}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x33}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x34}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x35}, - {1, 0x7003d5, 0x80}, - {1, 0x7003d4, 0x36}, - {1, 0x7003d5, 0x2}, - {1, 0x7003d4, 0x37}, - {1, 0x7003d5, 0x20}, - {1, 0x7003d4, 0x38}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x39}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x3a}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x3b}, - {1, 0x7003d5, 0x40}, - {1, 0x7003d4, 0x3c}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x3d}, - {1, 0x7003d5, 0xff}, - {1, 0x7003d4, 0x3e}, - {1, 0x7003d5, 0x46}, - {1, 0x7003d4, 0x3f}, - {1, 0x7003d5, 0x91}, - {1, 0x7003d4, 0x40}, - {1, 0x7003d5, 0xa3}, - {1, 0x7003d4, 0x41}, - {1, 0x7003d5, 0x7f}, - {1, 0x7003d4, 0x42}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x43}, - {1, 0x7003d5, 0x86}, - {1, 0x7003d4, 0x44}, - {1, 0x7003d5, 0x15}, - {1, 0x7003d4, 0x45}, - {1, 0x7003d5, 0x24}, - {1, 0x7003d4, 0x46}, - {1, 0x7003d5, 0xff}, - {1, 0x7003d4, 0x47}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x48}, - {1, 0x7003d5, 0x1}, - {1, 0x7003d4, 0x49}, - {1, 0x7003d5, 0x7}, - {1, 0x7003d4, 0x4a}, - {1, 0x7003d5, 0xe5}, - {1, 0x7003d4, 0x4b}, - {1, 0x7003d5, 0x20}, - {1, 0x7003d4, 0x4c}, - {1, 0x7003d5, 0x7f}, - {1, 0x7003d4, 0x4d}, - {1, 0x7003d5, 0x57}, - {1, 0x7003d4, 0x90}, - {1, 0x7003d5, 0x55}, - {1, 0x7003d4, 0x91}, - {1, 0x7003d5, 0xd5}, - {1, 0x7003d4, 0x92}, - {1, 0x7003d5, 0x5d}, - {1, 0x7003d4, 0x93}, - {1, 0x7003d5, 0xdd}, - {1, 0x7003d4, 0x94}, - {1, 0x7003d5, 0x86}, - {1, 0x7003d4, 0x95}, - {1, 0x7003d5, 0x17}, - {1, 0x7003d4, 0x96}, - {1, 0x7003d5, 0x8e}, - {1, 0x7003d4, 0x97}, - {1, 0x7003d5, 0xaa}, - {1, 0x7003d4, 0x98}, - {1, 0x7003d5, 0x8a}, - {1, 0x7003d4, 0x99}, - {1, 0x7003d5, 0xa3}, - {1, 0x7003d4, 0x9a}, - {1, 0x7003d5, 0xde}, - {1, 0x7003d4, 0x9b}, - {1, 0x7003d5, 0xab}, - {1, 0x7003d4, 0x9c}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x9d}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x9e}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0x9f}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0xa0}, - {1, 0x7003d5, 0x2}, - {1, 0x7003d4, 0xa1}, - {1, 0x7003d5, 0x2}, - {1, 0x7003d4, 0xa2}, - {1, 0x7003d5, 0x2}, - {1, 0x7003d4, 0xa3}, - {1, 0x7003d5, 0x15}, - {1, 0x7003d4, 0xa4}, - {1, 0x7003d5, 0x2}, - {1, 0x7003d4, 0xa5}, - {1, 0x7003d5, 0x6}, - {1, 0x7003d4, 0xa6}, - {1, 0x7003d5, 0x0}, - {1, 0x7003d4, 0xa7}, - {1, 0x7003d5, 0x0}, - {1, 0x7003c2, 0x67}, - {4, 0x40c00c, 0x0}, - {4, 0x40c040, 0x0}, - {4, 0x40c000, 0x20000}, - {4, 0x40c010, 0x1020100}, - {1, 0x7003c4, 0x16}, - {-1, 0x7003c5, 0x17} + {1, 0x3c4, 0x21}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x62}, + {1, 0x3c5, 0x7a}, + {1, 0x3c4, 0x6a}, + {1, 0x3c5, 0x16}, + {1, 0x3c4, 0x6b}, + {1, 0x3c5, 0x2}, + {1, 0x3c6, 0x0}, + {1, 0x3c4, 0x0}, + {1, 0x3c5, 0x1}, + {1, 0x3c2, 0xeb}, + {1, 0x3c4, 0x0}, + {1, 0x3c5, 0x3}, + {1, 0x3c4, 0x1}, + {1, 0x3c5, 0x1}, + {1, 0x3c4, 0x2}, + {1, 0x3c5, 0xf}, + {1, 0x3c4, 0x3}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x4}, + {1, 0x3c5, 0xe}, + {1, 0x3c4, 0x10}, + {1, 0x3c5, 0xc8}, + {1, 0x3c4, 0x11}, + {1, 0x3c5, 0x40}, + {1, 0x3c4, 0x12}, + {1, 0x3c5, 0x14}, + {1, 0x3c4, 0x13}, + {1, 0x3c5, 0x60}, + {1, 0x3c4, 0x14}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x15}, + {1, 0x3c5, 0xa}, + {1, 0x3c4, 0x16}, + {1, 0x3c5, 0x92}, + {1, 0x3c4, 0x17}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x18}, + {1, 0x3c5, 0x51}, + {1, 0x3c4, 0x19}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x1a}, + {1, 0x3c5, 0x1}, + {1, 0x3c4, 0x1b}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x1c}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x1d}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x1e}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x1f}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x20}, + {1, 0x3c5, 0xc4}, + {1, 0x3c4, 0x21}, + {1, 0x3c5, 0x30}, + {1, 0x3c4, 0x22}, + {1, 0x3c5, 0x2}, + {1, 0x3c4, 0x23}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x24}, + {1, 0x3c5, 0x1}, + {1, 0x3c4, 0x30}, + {1, 0x3c5, 0x28}, + {1, 0x3c4, 0x31}, + {1, 0x3c5, 0x3}, + {1, 0x3c4, 0x32}, + {1, 0x3c5, 0x24}, + {1, 0x3c4, 0x33}, + {1, 0x3c5, 0x9}, + {1, 0x3c4, 0x34}, + {1, 0x3c5, 0xc0}, + {1, 0x3c4, 0x35}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x36}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x37}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x38}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x39}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x3a}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x3b}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x3c}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x3d}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x3e}, + {1, 0x3c5, 0x3}, + {1, 0x3c4, 0x3f}, + {1, 0x3c5, 0xff}, + {1, 0x3c4, 0x40}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x41}, + {1, 0x3c5, 0xfc}, + {1, 0x3c4, 0x42}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x43}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x44}, + {1, 0x3c5, 0x20}, + {1, 0x3c4, 0x45}, + {1, 0x3c5, 0x18}, + {1, 0x3c4, 0x46}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x47}, + {1, 0x3c5, 0xfc}, + {1, 0x3c4, 0x48}, + {1, 0x3c5, 0x20}, + {1, 0x3c4, 0x49}, + {1, 0x3c5, 0xc}, + {1, 0x3c4, 0x4a}, + {1, 0x3c5, 0x44}, + {1, 0x3c4, 0x4b}, + {1, 0x3c5, 0x20}, + {1, 0x3c4, 0x4c}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x4d}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x4e}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x4f}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x50}, + {1, 0x3c5, 0x6}, + {1, 0x3c4, 0x51}, + {1, 0x3c5, 0x68}, + {1, 0x3c4, 0x52}, + {1, 0x3c5, 0xa7}, + {1, 0x3c4, 0x53}, + {1, 0x3c5, 0x7f}, + {1, 0x3c4, 0x54}, + {1, 0x3c5, 0x83}, + {1, 0x3c4, 0x55}, + {1, 0x3c5, 0x24}, + {1, 0x3c4, 0x56}, + {1, 0x3c5, 0xff}, + {1, 0x3c4, 0x57}, + {1, 0x3c5, 0x3}, + {1, 0x3c4, 0x58}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x59}, + {1, 0x3c5, 0x60}, + {1, 0x3c4, 0x5a}, + {1, 0x3c5, 0x59}, + {1, 0x3c4, 0x5b}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x5c}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x5d}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x5e}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x5f}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x60}, + {1, 0x3c5, 0x1}, + {1, 0x3c4, 0x61}, + {1, 0x3c5, 0x80}, + {1, 0x3c4, 0x63}, + {1, 0x3c5, 0x1a}, + {1, 0x3c4, 0x64}, + {1, 0x3c5, 0x1a}, + {1, 0x3c4, 0x65}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x66}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x67}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x68}, + {1, 0x3c5, 0x50}, + {1, 0x3c4, 0x69}, + {1, 0x3c5, 0x3}, + {1, 0x3c4, 0x6c}, + {1, 0x3c5, 0x52}, + {1, 0x3c4, 0x6d}, + {1, 0x3c5, 0x89}, + {1, 0x3c4, 0x6e}, + {1, 0x3c5, 0x9}, + {1, 0x3c4, 0x6f}, + {1, 0x3c5, 0x2}, + {1, 0x3c4, 0x70}, + {1, 0x3c5, 0x4}, + {1, 0x3c4, 0x71}, + {1, 0x3c5, 0x45}, + {1, 0x3c4, 0x72}, + {1, 0x3c5, 0x30}, + {1, 0x3c4, 0x73}, + {1, 0x3c5, 0x30}, + {1, 0x3c4, 0x74}, + {1, 0x3c5, 0x40}, + {1, 0x3c4, 0x75}, + {1, 0x3c5, 0x20}, + {1, 0x3c4, 0x80}, + {1, 0x3c5, 0xff}, + {1, 0x3c4, 0x81}, + {1, 0x3c5, 0x7}, + {1, 0x3c4, 0x82}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x83}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x84}, + {1, 0x3c5, 0x8}, + {1, 0x3c4, 0x85}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x86}, + {1, 0x3c5, 0x42}, + {1, 0x3c4, 0x87}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x88}, + {1, 0x3c5, 0x59}, + {1, 0x3c4, 0x89}, + {1, 0x3c5, 0x2}, + {1, 0x3c4, 0x8a}, + {1, 0x3c5, 0x44}, + {1, 0x3c4, 0x8b}, + {1, 0x3c5, 0x2}, + {1, 0x3c4, 0x8c}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x8d}, + {1, 0x3c5, 0xff}, + {1, 0x3c4, 0x8e}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x8f}, + {1, 0x3c5, 0x3a}, + {1, 0x3c4, 0x90}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x91}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x92}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0x93}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0xa0}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0xa1}, + {1, 0x3c5, 0x10}, + {1, 0x3c4, 0xa2}, + {1, 0x3c5, 0x8}, + {1, 0x3c4, 0xa3}, + {1, 0x3c5, 0x0}, + {1, 0x3c4, 0xa4}, + {1, 0x3c5, 0x2}, + {1, 0x3c4, 0xa5}, + {1, 0x3c5, 0xed}, + {1, 0x3c4, 0xa6}, + {1, 0x3c5, 0xed}, + {1, 0x3c4, 0xa7}, + {1, 0x3c5, 0xed}, + {1, 0x3c4, 0xa8}, + {1, 0x3c5, 0x7b}, + {1, 0x3c4, 0xa9}, + {1, 0x3c5, 0xfb}, + {1, 0x3c4, 0xaa}, + {1, 0x3c5, 0xff}, + {1, 0x3c4, 0xab}, + {1, 0x3c5, 0xff}, + {1, 0x3c4, 0xac}, + {1, 0x3c5, 0x97}, + {1, 0x3c4, 0xad}, + {1, 0x3c5, 0xef}, + {1, 0x3c4, 0xae}, + {1, 0x3c5, 0xbf}, + {1, 0x3c4, 0xaf}, + {1, 0x3c5, 0xdf}, + {1, 0x3ce, 0x0}, + {1, 0x3cf, 0x0}, + {1, 0x3ce, 0x1}, + {1, 0x3cf, 0x0}, + {1, 0x3ce, 0x2}, + {1, 0x3cf, 0x0}, + {1, 0x3ce, 0x3}, + {1, 0x3cf, 0x0}, + {1, 0x3ce, 0x4}, + {1, 0x3cf, 0x0}, + {1, 0x3ce, 0x5}, + {1, 0x3cf, 0x40}, + {1, 0x3ce, 0x6}, + {1, 0x3cf, 0x5}, + {1, 0x3ce, 0x7}, + {1, 0x3cf, 0xf}, + {1, 0x3ce, 0x8}, + {1, 0x3cf, 0xff}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x0}, + {-1, 0x3c1, 0x3e}, + {1, 0x3c0, 0x0}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x1}, + {-1, 0x3c1, 0x3b}, + {1, 0x3c0, 0x1}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x2}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0x2}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x3}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0x3}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x4}, + {-1, 0x3c1, 0x3b}, + {1, 0x3c0, 0x4}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x5}, + {-1, 0x3c1, 0x2f}, + {1, 0x3c0, 0x5}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x6}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0x6}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x7}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0x7}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x8}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0x8}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x9}, + {-1, 0x3c1, 0x3d}, + {1, 0x3c0, 0x9}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0xa}, + {-1, 0x3c1, 0x1f}, + {1, 0x3c0, 0xa}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0xb}, + {-1, 0x3c1, 0x1f}, + {1, 0x3c0, 0xb}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0xc}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0xc}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0xd}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0xd}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0xe}, + {-1, 0x3c1, 0x3f}, + {1, 0x3c0, 0xe}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0xf}, + {-1, 0x3c1, 0x2e}, + {1, 0x3c0, 0xf}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x10}, + {-1, 0x3c1, 0x0}, + {1, 0x3c0, 0x41}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x11}, + {-1, 0x3c1, 0x0}, + {1, 0x3c0, 0x0}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x12}, + {-1, 0x3c1, 0x0}, + {1, 0x3c0, 0xf}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x13}, + {-1, 0x3c1, 0x0}, + {1, 0x3c0, 0x0}, + {-1, 0x3da, 0x5}, + {1, 0x3c0, 0x14}, + {-1, 0x3c1, 0x0}, + {1, 0x3c0, 0x0}, + {1, 0x3d4, 0x0}, + {1, 0x3d5, 0xa3}, + {1, 0x3d4, 0x1}, + {1, 0x3d5, 0x7f}, + {1, 0x3d4, 0x2}, + {1, 0x3d5, 0x7f}, + {1, 0x3d4, 0x3}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x4}, + {1, 0x3d5, 0x85}, + {1, 0x3d4, 0x5}, + {1, 0x3d5, 0x16}, + {1, 0x3d4, 0x6}, + {1, 0x3d5, 0x24}, + {1, 0x3d4, 0x7}, + {1, 0x3d5, 0xf5}, + {1, 0x3d4, 0x8}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x9}, + {1, 0x3d5, 0x60}, + {1, 0x3d4, 0xa}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0xb}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0xc}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0xd}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0xe}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0xf}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x10}, + {1, 0x3d5, 0x3}, + {1, 0x3d4, 0x11}, + {1, 0x3d5, 0x9}, + {1, 0x3d4, 0x12}, + {1, 0x3d5, 0xff}, + {1, 0x3d4, 0x13}, + {1, 0x3d5, 0x80}, + {1, 0x3d4, 0x14}, + {1, 0x3d5, 0x40}, + {1, 0x3d4, 0x15}, + {1, 0x3d5, 0xff}, + {1, 0x3d4, 0x16}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x17}, + {1, 0x3d5, 0xe3}, + {1, 0x3d4, 0x18}, + {1, 0x3d5, 0xff}, + {1, 0x3d4, 0x30}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x31}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x32}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x33}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x34}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x35}, + {1, 0x3d5, 0x80}, + {1, 0x3d4, 0x36}, + {1, 0x3d5, 0x2}, + {1, 0x3d4, 0x37}, + {1, 0x3d5, 0x20}, + {1, 0x3d4, 0x38}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x39}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x3a}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x3b}, + {1, 0x3d5, 0x40}, + {1, 0x3d4, 0x3c}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x3d}, + {1, 0x3d5, 0xff}, + {1, 0x3d4, 0x3e}, + {1, 0x3d5, 0x46}, + {1, 0x3d4, 0x3f}, + {1, 0x3d5, 0x91}, + {1, 0x3d4, 0x40}, + {1, 0x3d5, 0xa3}, + {1, 0x3d4, 0x41}, + {1, 0x3d5, 0x7f}, + {1, 0x3d4, 0x42}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x43}, + {1, 0x3d5, 0x86}, + {1, 0x3d4, 0x44}, + {1, 0x3d5, 0x15}, + {1, 0x3d4, 0x45}, + {1, 0x3d5, 0x24}, + {1, 0x3d4, 0x46}, + {1, 0x3d5, 0xff}, + {1, 0x3d4, 0x47}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x48}, + {1, 0x3d5, 0x1}, + {1, 0x3d4, 0x49}, + {1, 0x3d5, 0x7}, + {1, 0x3d4, 0x4a}, + {1, 0x3d5, 0xe5}, + {1, 0x3d4, 0x4b}, + {1, 0x3d5, 0x20}, + {1, 0x3d4, 0x4c}, + {1, 0x3d5, 0x7f}, + {1, 0x3d4, 0x4d}, + {1, 0x3d5, 0x57}, + {1, 0x3d4, 0x90}, + {1, 0x3d5, 0x55}, + {1, 0x3d4, 0x91}, + {1, 0x3d5, 0xd5}, + {1, 0x3d4, 0x92}, + {1, 0x3d5, 0x5d}, + {1, 0x3d4, 0x93}, + {1, 0x3d5, 0xdd}, + {1, 0x3d4, 0x94}, + {1, 0x3d5, 0x86}, + {1, 0x3d4, 0x95}, + {1, 0x3d5, 0x17}, + {1, 0x3d4, 0x96}, + {1, 0x3d5, 0x8e}, + {1, 0x3d4, 0x97}, + {1, 0x3d5, 0xaa}, + {1, 0x3d4, 0x98}, + {1, 0x3d5, 0x8a}, + {1, 0x3d4, 0x99}, + {1, 0x3d5, 0xa3}, + {1, 0x3d4, 0x9a}, + {1, 0x3d5, 0xde}, + {1, 0x3d4, 0x9b}, + {1, 0x3d5, 0xab}, + {1, 0x3d4, 0x9c}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x9d}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x9e}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0x9f}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0xa0}, + {1, 0x3d5, 0x2}, + {1, 0x3d4, 0xa1}, + {1, 0x3d5, 0x2}, + {1, 0x3d4, 0xa2}, + {1, 0x3d5, 0x2}, + {1, 0x3d4, 0xa3}, + {1, 0x3d5, 0x15}, + {1, 0x3d4, 0xa4}, + {1, 0x3d5, 0x2}, + {1, 0x3d4, 0xa5}, + {1, 0x3d5, 0x6}, + {1, 0x3d4, 0xa6}, + {1, 0x3d5, 0x0}, + {1, 0x3d4, 0xa7}, + {1, 0x3d5, 0x0}, + {1, 0x3c2, 0x67}, }; From 2764da3ba20d7a5a1cf9d1b905810cb885937cfb Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Tue, 10 Aug 2010 16:32:48 +0200 Subject: [PATCH 494/503] 2010-08-10 Yves Blusseau * util/grub-macho2img.c (main): fix typo --- ChangeLog | 4 ++++ util/grub-macho2img.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0829eb83e..86f3246bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-10 Yves Blusseau + + * util/grub-macho2img.c (main): fix typo + 2010-08-10 Vladimir Serbinenko * include/grub/vga.h (grub_vga_gr_write): Add GRUB_MACHINE_PCI_IO_BASE. diff --git a/util/grub-macho2img.c b/util/grub-macho2img.c index 8683587be..23ffafb04 100644 --- a/util/grub-macho2img.c +++ b/util/grub-macho2img.c @@ -79,7 +79,7 @@ main (int argc, char **argv) fclose (in); fclose (out); free (buf); - printf ("Invalid Mach-O fle\n"); + printf ("Invalid Mach-O file\n"); return 4; } curcmd = (struct grub_macho_segment32 *) (buf + sizeof (*head)); From f0206638bf28aa05a8971cb9318a3e126233a6bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 11 Aug 2010 04:00:06 +0200 Subject: [PATCH 495/503] * include/grub/vga.h: Add missing grub/pci.h include. --- ChangeLog | 4 ++++ include/grub/vga.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 86f3246bd..1f5efd32a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-10 Vladimir Serbinenko + + * include/grub/vga.h: Add missing grub/pci.h include. + 2010-08-10 Yves Blusseau * util/grub-macho2img.c (main): fix typo diff --git a/include/grub/vga.h b/include/grub/vga.h index 0ca56e37f..5f321d589 100644 --- a/include/grub/vga.h +++ b/include/grub/vga.h @@ -19,6 +19,8 @@ #ifndef GRUB_VGA_HEADER #define GRUB_VGA_HEADER 1 +#include + enum { GRUB_VGA_IO_ARX = 0x3c0, From f947ab49b03350df958528214304ccafd8599b71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 11 Aug 2010 04:18:07 +0200 Subject: [PATCH 496/503] Remove the dump of sm712 initialisation sequence. * include/grub/pci.h (GRUB_PCI_CLASS_SUBCLASS_VGA): New const. * include/grub/vga.h (GRUB_VGA_IO_ARX_READ): New register. (GRUB_VGA_IO_MISC_WRITE): Likewise. (GRUB_VGA_CR_*): Added many registers. (GRUB_VGA_SR_*): Likewise. (GRUB_VGA_GR_*): Likewise. (grub_vga_write_arx): New function. (grub_video_hw_config): New struct. (grub_vga_set_geometry): New function. * kern/i386/qemu/init.c (load_palette): Use grub_vga_write_arx and GRUB_PCI_CLASS_SUBCLASS_VGA. * video/cirrus.c (grub_video_cirrus_setup): Use grub_vga_set_geometry. * video/sm712.c (grub_sm712_write_reg): New function (grub_sm712_read_reg): Likewise. (grub_sm712_sr_write): Likewise. (grub_sm712_gr_write): Likewise. (grub_sm712_cr_write): Likewise. (grub_sm712_write_arx): Likewise. (grub_sm712_cr_shadow_write): Likewise. (grub_sm712_write_dda_lookup): Likewise. (grub_video_sm712_setup): Initialise the video rather then blindly replay the dump. (main) [TEST]: Add a routine to be able to compile as standalone for tests. * video/sm712_init.c (sm712_init): Removed. (sm712_sr_seq1): New array. (sm712_sr_seq2): Likewise. --- ChangeLog | 32 +++ include/grub/pci.h | 1 + include/grub/vga.h | 183 +++++++++++++- kern/i386/qemu/init.c | 15 +- video/cirrus.c | 35 +-- video/sm712.c | 558 ++++++++++++++++++++++++++++++++++++++++-- video/sm712_init.c | 552 +---------------------------------------- 7 files changed, 772 insertions(+), 604 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f5efd32a..5d9d7a759 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2010-08-11 Vladimir Serbinenko + + Remove the dump of sm712 initialisation sequence. + + * include/grub/pci.h (GRUB_PCI_CLASS_SUBCLASS_VGA): New const. + * include/grub/vga.h (GRUB_VGA_IO_ARX_READ): New register. + (GRUB_VGA_IO_MISC_WRITE): Likewise. + (GRUB_VGA_CR_*): Added many registers. + (GRUB_VGA_SR_*): Likewise. + (GRUB_VGA_GR_*): Likewise. + (grub_vga_write_arx): New function. + (grub_video_hw_config): New struct. + (grub_vga_set_geometry): New function. + * kern/i386/qemu/init.c (load_palette): Use grub_vga_write_arx and + GRUB_PCI_CLASS_SUBCLASS_VGA. + * video/cirrus.c (grub_video_cirrus_setup): Use grub_vga_set_geometry. + * video/sm712.c (grub_sm712_write_reg): New function + (grub_sm712_read_reg): Likewise. + (grub_sm712_sr_write): Likewise. + (grub_sm712_gr_write): Likewise. + (grub_sm712_cr_write): Likewise. + (grub_sm712_write_arx): Likewise. + (grub_sm712_cr_shadow_write): Likewise. + (grub_sm712_write_dda_lookup): Likewise. + (grub_video_sm712_setup): Initialise the video rather then + blindly replay the dump. + (main) [TEST]: Add a routine to be able to compile as standalone for + tests. + * video/sm712_init.c (sm712_init): Removed. + (sm712_sr_seq1): New array. + (sm712_sr_seq2): Likewise. + 2010-08-10 Vladimir Serbinenko * include/grub/vga.h: Add missing grub/pci.h include. diff --git a/include/grub/pci.h b/include/grub/pci.h index e6d6488f0..f34e3d907 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -80,6 +80,7 @@ #define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9 #define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 +#define GRUB_PCI_CLASS_SUBCLASS_VGA 0x0300 #ifndef ASM_FILE typedef grub_uint32_t grub_pci_id_t; diff --git a/include/grub/vga.h b/include/grub/vga.h index 5f321d589..7f112d83a 100644 --- a/include/grub/vga.h +++ b/include/grub/vga.h @@ -24,6 +24,8 @@ enum { GRUB_VGA_IO_ARX = 0x3c0, + GRUB_VGA_IO_ARX_READ = 0x3c1, + GRUB_VGA_IO_MISC_WRITE = 0x3c2, GRUB_VGA_IO_SR_INDEX = 0x3c4, GRUB_VGA_IO_SR_DATA = 0x3c5, GRUB_VGA_IO_PIXEL_MASK = 0x3c6, @@ -41,8 +43,15 @@ enum enum { - GRUB_VGA_CR_WIDTH = 0x01, + GRUB_VGA_CR_HTOTAL = 0x00, + GRUB_VGA_CR_HORIZ_END = 0x01, + GRUB_VGA_CR_HBLANK_START = 0x02, + GRUB_VGA_CR_HBLANK_END = 0x03, + GRUB_VGA_CR_HORIZ_SYNC_PULSE_START = 0x04, + GRUB_VGA_CR_HORIZ_SYNC_PULSE_END = 0x05, + GRUB_VGA_CR_VERT_TOTAL = 0x06, GRUB_VGA_CR_OVERFLOW = 0x07, + GRUB_VGA_CR_BYTE_PANNING = 0x08, GRUB_VGA_CR_CELL_HEIGHT = 0x09, GRUB_VGA_CR_CURSOR_START = 0x0a, GRUB_VGA_CR_CURSOR_END = 0x0b, @@ -50,14 +59,71 @@ enum GRUB_VGA_CR_START_ADDR_LOW_REGISTER = 0x0d, GRUB_VGA_CR_CURSOR_ADDR_HIGH = 0x0e, GRUB_VGA_CR_CURSOR_ADDR_LOW = 0x0f, + GRUB_VGA_CR_VSYNC_START = 0x10, GRUB_VGA_CR_VSYNC_END = 0x11, - GRUB_VGA_CR_HEIGHT = 0x12, + GRUB_VGA_CR_VDISPLAY_END = 0x12, GRUB_VGA_CR_PITCH = 0x13, + GRUB_VGA_CR_UNDERLINE_LOCATION = 0x14, + GRUB_VGA_CR_VERTICAL_BLANK_START = 0x15, + GRUB_VGA_CR_VERTICAL_BLANK_END = 0x16, GRUB_VGA_CR_MODE = 0x17, GRUB_VGA_CR_LINE_COMPARE = 0x18, }; +enum + { + GRUB_VGA_CR_BYTE_PANNING_NORMAL = 0 + }; + +enum + { + GRUB_VGA_CR_UNDERLINE_LOCATION_DWORD_MODE = 0x40 + }; + +enum + { + GRUB_VGA_IO_MISC_COLOR = 0x01, + GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS = 0x02, + GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 = 0x08, + GRUB_VGA_IO_MISC_28MHZ = 0x04, + GRUB_VGA_IO_MISC_UPPER_64K = 0x20, + GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY = 0x40, + GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY = 0x80, + }; + +enum + { + GRUB_VGA_ARX_MODE = 0x10, + GRUB_VGA_ARX_OVERSCAN = 0x11, + GRUB_VGA_ARX_COLOR_PLANE_ENABLE = 0x12, + GRUB_VGA_ARX_HORIZONTAL_PANNING = 0x13, + GRUB_VGA_ARX_COLOR_SELECT = 0x14 + }; + +enum + { + GRUB_VGA_ARX_MODE_TEXT = 0x00, + GRUB_VGA_ARX_MODE_GRAPHICS = 0x01, + GRUB_VGA_ARX_MODE_ENABLE_256COLOR = 0x40 + }; + #define GRUB_VGA_CR_WIDTH_DIVISOR 8 + +#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT 7 +#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK 0x02 +#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT 3 +#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK 0x40 + +#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT 8 +#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_MASK 0x01 +#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT 4 +#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_MASK 0x20 + +#define GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT 6 +#define GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK 0x04 +#define GRUB_VGA_CR_OVERFLOW_VSYNC_START2_SHIFT 2 +#define GRUB_VGA_CR_OVERFLOW_VSYNC_START2_MASK 0x80 + #define GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT 7 #define GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK 0x02 #define GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT 3 @@ -67,7 +133,9 @@ enum #define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40 #define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3 - +#define GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK 0x20 +#define GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT 4 +#define GRUB_VGA_CR_CELL_HEIGHT_DOUBLE_SCAN 0x80 enum { GRUB_VGA_CR_CURSOR_START_DISABLE = (1 << 5) @@ -79,17 +147,26 @@ enum { GRUB_VGA_CR_MODE_NO_CGA = 0x01, GRUB_VGA_CR_MODE_NO_HERCULES = 0x02, + GRUB_VGA_CR_MODE_ADDRESS_WRAP = 0x20, GRUB_VGA_CR_MODE_BYTE_MODE = 0x40, GRUB_VGA_CR_MODE_TIMING_ENABLE = 0x80 }; enum { + GRUB_VGA_SR_RESET = 0, GRUB_VGA_SR_CLOCKING_MODE = 1, GRUB_VGA_SR_MAP_MASK_REGISTER = 2, + GRUB_VGA_SR_CHAR_MAP_SELECT = 3, GRUB_VGA_SR_MEMORY_MODE = 4, }; +enum + { + GRUB_VGA_SR_RESET_ASYNC = 1, + GRUB_VGA_SR_RESET_SYNC = 2 + }; + enum { GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK = 1 @@ -98,19 +175,33 @@ enum enum { GRUB_VGA_SR_MEMORY_MODE_NORMAL = 0, - GRUB_VGA_SR_MEMORY_MODE_CHAIN4 = 8 + GRUB_VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY = 2, + GRUB_VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING = 4, + GRUB_VGA_SR_MEMORY_MODE_CHAIN4 = 8, }; enum { + GRUB_VGA_GR_SET_RESET_PLANE = 0, + GRUB_VGA_GR_SET_RESET_PLANE_ENABLE = 1, + GRUB_VGA_GR_COLOR_COMPARE = 2, GRUB_VGA_GR_DATA_ROTATE = 3, GRUB_VGA_GR_READ_MAP_REGISTER = 4, GRUB_VGA_GR_MODE = 5, GRUB_VGA_GR_GR6 = 6, + GRUB_VGA_GR_COLOR_COMPARE_DISABLE = 7, GRUB_VGA_GR_BITMASK = 8, GRUB_VGA_GR_MAX }; +#define GRUB_VGA_ALL_PLANES 0xf +#define GRUB_VGA_NO_PLANES 0x0 + +enum + { + GRUB_VGA_GR_DATA_ROTATE_NOP = 0 + }; + enum { GRUB_VGA_TEXT_TEXT_PLANE = 0, @@ -121,6 +212,7 @@ enum enum { GRUB_VGA_GR_GR6_GRAPHICS_MODE = 1, + GRUB_VGA_GR_GR6_MMAP_A0 = (1 << 2), GRUB_VGA_GR_GR6_MMAP_CGA = (3 << 2) }; @@ -128,6 +220,7 @@ enum { GRUB_VGA_GR_MODE_READ_MODE1 = 0x08, GRUB_VGA_GR_MODE_ODD_EVEN = 0x10, + GRUB_VGA_GR_MODE_ODD_EVEN_SHIFT = 0x20, GRUB_VGA_GR_MODE_256_COLOR = 0x40 }; @@ -193,4 +286,86 @@ grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, grub_outb (b, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); } +static inline void +grub_vga_write_arx (grub_uint8_t val, grub_uint8_t addr) +{ + grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER); + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); + grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ); + grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); +} + +struct grub_video_hw_config +{ + unsigned vertical_total; + unsigned vertical_blank_start; + unsigned vertical_blank_end; + unsigned vertical_sync_start; + unsigned vertical_sync_end; + unsigned line_compare; + unsigned vdisplay_end; + unsigned pitch; + unsigned horizontal_total; + unsigned horizontal_blank_start; + unsigned horizontal_blank_end; + unsigned horizontal_sync_pulse_start; + unsigned horizontal_sync_pulse_end; + unsigned horizontal_end; +}; + +static inline void +grub_vga_set_geometry (struct grub_video_hw_config *config, + void (*cr_write) (grub_uint8_t val, grub_uint8_t addr)) +{ + unsigned vertical_total = config->vertical_total - 2; + unsigned vertical_blank_start = config->vertical_blank_start - 1; + unsigned vdisplay_end = config->vdisplay_end - 1; + grub_uint8_t overflow, cell_height_reg; + + /* Disable CR0-7 write protection. */ + cr_write (0, GRUB_VGA_CR_VSYNC_END); + + overflow = ((vertical_total >> GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT) + & GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_MASK) + | ((vertical_total >> GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT) + & GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_MASK) + | ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START2_SHIFT) + & GRUB_VGA_CR_OVERFLOW_VSYNC_START2_MASK) + | ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT) + & GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK) + | ((vdisplay_end >> GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT) + & GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK) + | ((vdisplay_end >> GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT) + & GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK) + | ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT) + & GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK) + | ((config->line_compare >> GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT) + & GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK); + + cell_height_reg = ((vertical_blank_start + >> GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT) + & GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK) + | ((config->line_compare >> GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT) + & GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK); + + cr_write (config->horizontal_total - 1, GRUB_VGA_CR_HTOTAL); + cr_write (config->horizontal_end - 1, GRUB_VGA_CR_HORIZ_END); + cr_write (config->horizontal_blank_start - 1, GRUB_VGA_CR_HBLANK_START); + cr_write (config->horizontal_blank_end, GRUB_VGA_CR_HBLANK_END); + cr_write (config->horizontal_sync_pulse_start, + GRUB_VGA_CR_HORIZ_SYNC_PULSE_START); + cr_write (config->horizontal_sync_pulse_end, + GRUB_VGA_CR_HORIZ_SYNC_PULSE_END); + cr_write (vertical_total & 0xff, GRUB_VGA_CR_VERT_TOTAL); + cr_write (overflow, GRUB_VGA_CR_OVERFLOW); + cr_write (cell_height_reg, GRUB_VGA_CR_CELL_HEIGHT); + cr_write (config->vertical_sync_start & 0xff, GRUB_VGA_CR_VSYNC_START); + cr_write (config->vertical_sync_end & 0x0f, GRUB_VGA_CR_VSYNC_END); + cr_write (vdisplay_end & 0xff, GRUB_VGA_CR_VDISPLAY_END); + cr_write (config->pitch & 0xff, GRUB_VGA_CR_PITCH); + cr_write (vertical_blank_start & 0xff, GRUB_VGA_CR_VERTICAL_BLANK_START); + cr_write (config->vertical_blank_end & 0xff, GRUB_VGA_CR_VERTICAL_BLANK_END); + cr_write (config->line_compare & 0xff, GRUB_VGA_CR_LINE_COMPARE); +} + #endif diff --git a/kern/i386/qemu/init.c b/kern/i386/qemu/init.c index 201ba3633..bd12953df 100644 --- a/kern/i386/qemu/init.c +++ b/kern/i386/qemu/init.c @@ -69,10 +69,7 @@ load_palette (void) { unsigned i; for (i = 0; i < 16; i++) - { - grub_outb (i, GRUB_VGA_IO_ARX); - grub_outb (i, GRUB_VGA_IO_ARX); - } + grub_vga_write_arx (i, i); for (i = 0; i < ARRAY_SIZE (colors); i++) grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b); @@ -90,7 +87,7 @@ grub_qemu_init_cirrus (void) addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); - if (((class >> 16) & 0xffff) != 0x0300) + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA) return 0; /* FIXME: chooose addresses dynamically. */ @@ -110,7 +107,7 @@ grub_qemu_init_cirrus (void) grub_pci_iterate (find_card); - grub_outb (1, 0x3c2); + grub_outb (GRUB_VGA_IO_MISC_COLOR, GRUB_VGA_IO_MISC_WRITE); load_font (); @@ -137,10 +134,8 @@ grub_qemu_init_cirrus (void) load_palette (); - grub_outb (0x10, 0x3c0); - grub_outb (0, 0x3c1); - grub_outb (0x14, 0x3c0); - grub_outb (0, 0x3c1); + grub_vga_write_arx (GRUB_VGA_ARX_MODE_TEXT, GRUB_VGA_ARX_MODE); + grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT); grub_vga_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK, GRUB_VGA_SR_CLOCKING_MODE); diff --git a/video/cirrus.c b/video/cirrus.c index ccbab9d15..b8b0142ad 100644 --- a/video/cirrus.c +++ b/video/cirrus.c @@ -334,43 +334,26 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, } { - int pitch_reg, overflow_reg = 0, line_compare = 0x3ff; + struct grub_video_hw_config config = { + .pitch = pitch / GRUB_VGA_CR_PITCH_DIVISOR, + .line_compare = 0x3ff, + .vdisplay_end = height - 1, + .horizontal_end = width / GRUB_VGA_CR_WIDTH_DIVISOR + }; grub_uint8_t sr_ext = 0, hidden_dac = 0; - pitch_reg = pitch / GRUB_VGA_CR_PITCH_DIVISOR; - + grub_vga_set_geometry (&config, grub_vga_cr_write); + grub_vga_gr_write (GRUB_VGA_GR_MODE_256_COLOR | GRUB_VGA_GR_MODE_READ_MODE1, GRUB_VGA_GR_MODE); grub_vga_gr_write (GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6); grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE); - /* Disable CR0-7 write protection. */ - grub_vga_cr_write (0, GRUB_VGA_CR_VSYNC_END); - - grub_vga_cr_write (width / GRUB_VGA_CR_WIDTH_DIVISOR - 1, - GRUB_VGA_CR_WIDTH); - grub_vga_cr_write ((height - 1) & 0xff, GRUB_VGA_CR_HEIGHT); - overflow_reg |= (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT) & - GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK) - | (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT) & - GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK); - - grub_vga_cr_write (pitch_reg & 0xff, GRUB_VGA_CR_PITCH); - - grub_vga_cr_write (line_compare & 0xff, GRUB_VGA_CR_LINE_COMPARE); - overflow_reg |= (line_compare >> GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT) - & GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK; - - grub_vga_cr_write (overflow_reg, GRUB_VGA_CR_OVERFLOW); - - grub_vga_cr_write ((pitch_reg >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT) + grub_vga_cr_write ((config.pitch >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT) & CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK, CIRRUS_CR_EXTENDED_DISPLAY); - grub_vga_cr_write ((line_compare >> GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT) - & GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK, GRUB_VGA_CR_CELL_HEIGHT); - grub_vga_cr_write (GRUB_VGA_CR_MODE_TIMING_ENABLE | GRUB_VGA_CR_MODE_BYTE_MODE | GRUB_VGA_CR_MODE_NO_HERCULES | GRUB_VGA_CR_MODE_NO_CGA, diff --git a/video/sm712.c b/video/sm712.c index db7494a62..60f2c9089 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -32,6 +32,162 @@ #define GRUB_SM712_TOTAL_MEMORY_SPACE 0x700400 #define GRUB_SM712_REG_BASE 0x700000 +#define GRUB_SM712_PCIID 0x0712126f + +enum + { + GRUB_SM712_SR_TV_CONTROL = 0x65, + GRUB_SM712_SR_RAM_LUT = 0x66, + GRUB_SM712_SR_CLOCK_CONTROL1 = 0x68, + GRUB_SM712_SR_CLOCK_CONTROL2 = 0x69, + GRUB_SM712_SR_VCLK_NUM = 0x6c, + GRUB_SM712_SR_VCLK_DENOM = 0x6d, + GRUB_SM712_SR_VCLK2_NUM = 0x6e, + GRUB_SM712_SR_VCLK2_DENOM = 0x6f, + GRUB_SM712_SR_POPUP_ICON_LOW = 0x80, + GRUB_SM712_SR_POPUP_ICON_HIGH = 0x81, + GRUB_SM712_SR_POPUP_ICON_CTRL = 0x82, + GRUB_SM712_SR_POPUP_ICON_COLOR1 = 0x84, + GRUB_SM712_SR_POPUP_ICON_COLOR2 = 0x85, + GRUB_SM712_SR_POPUP_ICON_COLOR3 = 0x86, + + GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW = 0x88, + GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH = 0x89, + GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW = 0x8a, + GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH = 0x8b, + GRUB_SM712_SR_HW_CURSOR_FG_COLOR = 0x8c, + GRUB_SM712_SR_HW_CURSOR_BG_COLOR = 0x8d, + + GRUB_SM712_SR_POPUP_ICON_X_LOW = 0x90, + GRUB_SM712_SR_POPUP_ICON_X_HIGH = 0x91, + GRUB_SM712_SR_POPUP_ICON_Y_LOW = 0x92, + GRUB_SM712_SR_POPUP_ICON_Y_HIGH = 0x93, + GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL = 0xa0, + GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW = 0xa1, + GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH = 0xa2, + GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW = 0xa3, + GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH = 0xa4, + GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT = 0xa5, + GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT = 0xa6, + GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT = 0xa7, + GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY = 0xa8, + GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY = 0xa9, + GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY = 0xaa, + GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY = 0xab, + GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY = 0xac, + GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY = 0xad, + GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR = 0xae, + GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR = 0xaf, + }; +enum + { + GRUB_SM712_SR_TV_CRT_SRAM = 0x00, + GRUB_SM712_SR_TV_LCD_SRAM = 0x08 + }; +enum + { + GRUB_SM712_SR_TV_ALT_CLOCK = 0x00, + GRUB_SM712_SR_TV_FREE_RUN_CLOCK = 0x04 + }; +enum + { + GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC = 0x00, + GRUB_SM712_SR_TV_CLOCK_REFCLK_PAL = 0x04 + }; +enum + { + GRUB_SM712_SR_TV_HSYNC = 0x00, + GRUB_SM712_SR_TV_COMPOSITE_HSYNC = 0x01 + }; +enum + { + GRUB_SM712_SR_RAM_LUT_NORMAL = 0, + GRUB_SM712_SR_RAM_LUT_LCD_RAM_OFF = 0x80, + GRUB_SM712_SR_RAM_LUT_CRT_RAM_OFF = 0x40, + GRUB_SM712_SR_RAM_LUT_LCD_RAM_NO_WRITE = 0x20, + GRUB_SM712_SR_RAM_LUT_CRT_RAM_NO_WRITE = 0x10, + GRUB_SM712_SR_RAM_LUT_CRT_8BIT = 0x08, + GRUB_SM712_SR_RAM_LUT_CRT_GAMMA = 0x04 + }; + +enum + { + GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR = 0x40, + GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK = 0x10, + }; + +enum + { + GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK = 0x03 + }; + +#define GRUB_SM712_SR_POPUP_ICON_HIGH_MASK 0x7 +#define GRUB_SM712_SR_POPUP_ICON_HIGH_HW_CURSOR_EN 0x80 + enum + { + GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED = 0, + GRUB_SM712_SR_POPUP_ICON_CTRL_ZOOM_ENABLED = 0x40, + GRUB_SM712_SR_POPUP_ICON_CTRL_ENABLED = 0x80 + }; +#define RGB332_BLACK 0 +#define RGB332_WHITE 0xff + + enum + { + GRUB_SM712_CR_OVERFLOW_INTERLACE = 0x30, + GRUB_SM712_CR_INTERLACE_RETRACE = 0x31, + GRUB_SM712_CR_TV_VDISPLAY_START = 0x32, + GRUB_SM712_CR_TV_VDISPLAY_END_HIGH = 0x33, + GRUB_SM712_CR_TV_VDISPLAY_END_LOW = 0x34, + GRUB_SM712_CR_DDA_CONTROL_LOW = 0x35, + GRUB_SM712_CR_DDA_CONTROL_HIGH = 0x36, + GRUB_SM712_CR_TV_EQUALIZER = 0x38, + GRUB_SM712_CR_TV_SERRATION = 0x39, + GRUB_SM712_CR_HSYNC_CTRL = 0x3a, + GRUB_SM712_CR_DEBUG = 0x3c, + GRUB_SM712_CR_SHADOW_VGA_HTOTAL = 0x40, + GRUB_SM712_CR_SHADOW_VGA_HBLANK_START = 0x41, + GRUB_SM712_CR_SHADOW_VGA_HBLANK_END = 0x42, + GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START = 0x43, + GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END = 0x44, + GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL = 0x45, + GRUB_SM712_CR_SHADOW_VGA_VBLANK_START = 0x46, + GRUB_SM712_CR_SHADOW_VGA_VBLANK_END = 0x47, + GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START = 0x48, + GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END = 0x49, + GRUB_SM712_CR_SHADOW_VGA_OVERFLOW = 0x4a, + GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT = 0x4b, + GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END = 0x4c, + GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END = 0x4d, + GRUB_SM712_CR_DDA_LOOKUP_REG3_START = 0x90, + GRUB_SM712_CR_DDA_LOOKUP_REG2_START = 0x91, + GRUB_SM712_CR_DDA_LOOKUP_REG1_START = 0xa0, + GRUB_SM712_CR_VCENTERING_OFFSET = 0xa6, + GRUB_SM712_CR_HCENTERING_OFFSET = 0xa7, + }; + +#define GRUB_SM712_CR_DEBUG_NONE 0 + +#define SM712_DDA_REG3_COMPARE_SHIFT 2 +#define SM712_DDA_REG3_COMPARE_MASK 0xfc +#define SM712_DDA_REG3_DDA_SHIFT 8 +#define SM712_DDA_REG3_DDA_MASK 0x3 +#define SM712_DDA_REG2_DDA_MASK 0xff +#define SM712_DDA_REG2_VCENTER_MASK 0x3f + +static struct +{ + grub_uint8_t compare; + grub_uint16_t dda; + grub_uint8_t vcentering; +} dda_lookups[] = { + { 21, 469, 2}, + { 23, 477, 2}, + { 33, 535, 2}, + { 35, 682, 21}, + { 34, 675, 2}, + { 55, 683, 6}, +}; static struct { @@ -44,6 +200,7 @@ static struct grub_pci_device_t dev; } framebuffer; +#ifndef TEST static grub_err_t grub_video_sm712_video_init (void) { @@ -62,14 +219,117 @@ grub_video_sm712_video_fini (void) return grub_video_fb_fini (); } +#endif + +static inline void +grub_sm712_write_reg (grub_uint8_t val, grub_uint16_t addr) +{ +#ifdef TEST + printf (" {1, 0x%x, 0x%x},\n", addr, val); +#else + *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE + + addr) = val; +#endif +} + +static inline grub_uint8_t +grub_sm712_read_reg (grub_uint16_t addr) +{ +#ifdef TEST + printf (" {-1, 0x%x, 0x5},\n", addr); +#else + return *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE + + addr); +#endif +} static inline grub_uint8_t grub_sm712_sr_read (grub_uint8_t addr) { - *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE - + GRUB_VGA_IO_SR_INDEX) = addr; - return *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE - + GRUB_VGA_IO_SR_DATA); + grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX); + return grub_sm712_read_reg (GRUB_VGA_IO_SR_DATA); +} + +static inline void +grub_sm712_sr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX); + grub_sm712_write_reg (val, GRUB_VGA_IO_SR_DATA); +} + +static inline void +grub_sm712_gr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_sm712_write_reg (addr, GRUB_VGA_IO_GR_INDEX); + grub_sm712_write_reg (val, GRUB_VGA_IO_GR_DATA); +} + +static inline void +grub_sm712_cr_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_sm712_write_reg (addr, GRUB_VGA_IO_CR_INDEX); + grub_sm712_write_reg (val, GRUB_VGA_IO_CR_DATA); +} + +static inline void +grub_sm712_write_arx (grub_uint8_t val, grub_uint8_t addr) +{ + grub_sm712_read_reg (GRUB_VGA_IO_INPUT_STATUS1_REGISTER); + grub_sm712_write_reg (addr, GRUB_VGA_IO_ARX); + grub_sm712_read_reg (GRUB_VGA_IO_ARX_READ); + grub_sm712_write_reg (val, GRUB_VGA_IO_ARX); +} + +static inline void +grub_sm712_cr_shadow_write (grub_uint8_t val, grub_uint8_t addr) +{ + grub_uint8_t mapping[] = + { + [GRUB_VGA_CR_HTOTAL] = GRUB_SM712_CR_SHADOW_VGA_HTOTAL, + [GRUB_VGA_CR_HORIZ_END] = 0xff, + [GRUB_VGA_CR_HBLANK_START] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_START, + [GRUB_VGA_CR_HBLANK_END] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_END, + [GRUB_VGA_CR_HORIZ_SYNC_PULSE_START] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START, + [GRUB_VGA_CR_HORIZ_SYNC_PULSE_END] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END, + [GRUB_VGA_CR_VERT_TOTAL] = GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL, + [GRUB_VGA_CR_OVERFLOW] = GRUB_SM712_CR_SHADOW_VGA_OVERFLOW, + [GRUB_VGA_CR_BYTE_PANNING] = 0xff, + [GRUB_VGA_CR_CELL_HEIGHT] = GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT, + [GRUB_VGA_CR_CURSOR_START] = 0xff, + [GRUB_VGA_CR_CURSOR_END] = 0xff, + [GRUB_VGA_CR_START_ADDR_HIGH_REGISTER] = 0xff, + [GRUB_VGA_CR_START_ADDR_LOW_REGISTER] = 0xff, + [GRUB_VGA_CR_CURSOR_ADDR_HIGH] = 0xff, + [GRUB_VGA_CR_CURSOR_ADDR_LOW] = 0xff, + [GRUB_VGA_CR_VSYNC_START] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START, + [GRUB_VGA_CR_VSYNC_END] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END, + [GRUB_VGA_CR_VDISPLAY_END] = GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END, + [GRUB_VGA_CR_PITCH] = GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END, + [GRUB_VGA_CR_UNDERLINE_LOCATION] = 0xff, + + [GRUB_VGA_CR_VERTICAL_BLANK_START] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_START, + [GRUB_VGA_CR_VERTICAL_BLANK_END] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_END, + [GRUB_VGA_CR_MODE] = 0xff, + [GRUB_VGA_CR_LINE_COMPARE] = 0xff + }; + if (addr >= ARRAY_SIZE (mapping) || mapping[addr] == 0xff) + return; + grub_sm712_cr_write (val, mapping[addr]); +} + +static inline void +grub_sm712_write_dda_lookup (int idx, grub_uint8_t compare, grub_uint16_t dda, + grub_uint8_t vcentering) +{ + grub_sm712_cr_write (((compare << SM712_DDA_REG3_COMPARE_SHIFT) + & SM712_DDA_REG3_COMPARE_MASK) + | ((dda >> SM712_DDA_REG3_DDA_SHIFT) + & SM712_DDA_REG3_DDA_MASK), + GRUB_SM712_CR_DDA_LOOKUP_REG3_START + 2 * idx); + grub_sm712_cr_write (dda & SM712_DDA_REG2_DDA_MASK, + GRUB_SM712_CR_DDA_LOOKUP_REG2_START + 2 * idx); + grub_sm712_cr_write (vcentering & SM712_DDA_REG2_VCENTER_MASK, + GRUB_SM712_CR_DDA_LOOKUP_REG1_START + idx); } static grub_err_t @@ -81,6 +341,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, int found = 0; unsigned i; +#ifndef TEST auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) { @@ -90,7 +351,8 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); - if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f) + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + || pciid != GRUB_SM712_PCIID) return 0; found = 1; @@ -114,7 +376,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, grub_pci_iterate (find_card); if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); - +#endif /* Fill mode info details. */ framebuffer.mode_info.width = 1024; framebuffer.mode_info.height = 600; @@ -131,8 +393,12 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, framebuffer.mode_info.blue_field_pos = 0; framebuffer.mode_info.reserved_mask_size = 0; framebuffer.mode_info.reserved_field_pos = 0; - framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); +#ifndef TEST + framebuffer.mode_info.blit_format + = grub_video_get_blit_format (&framebuffer.mode_info); +#endif +#ifndef TEST if (found && framebuffer.base == 0) { grub_pci_address_t addr; @@ -150,47 +416,280 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); grub_pci_write (addr, 0x7); } +#endif /* We can safely discard volatile attribute. */ +#ifndef TEST framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, framebuffer.base, GRUB_SM712_TOTAL_MEMORY_SPACE); +#endif framebuffer.mapped = 1; /* Initialise SM712. */ +#ifndef TEST + /* FIXME */ grub_vga_sr_write (0x11, 0x18); +#endif +#ifndef TEST /* Prevent garbage from appearing on the screen. */ grub_memset (framebuffer.ptr, 0, framebuffer.mode_info.height * framebuffer.mode_info.pitch); +#endif - for (i = 0; i < ARRAY_SIZE (sm712_init); i++) - switch (sm712_init[i].directive) + /* FIXME */ + grub_sm712_sr_write (0, 0x21); + grub_sm712_sr_write (0x7a, 0x62); + grub_sm712_sr_write (0x16, 0x6a); + grub_sm712_sr_write (0x2, 0x6b); + grub_sm712_write_reg (0, GRUB_VGA_IO_PIXEL_MASK); + grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC, GRUB_VGA_SR_RESET); + grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY + | GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY + | GRUB_VGA_IO_MISC_UPPER_64K + | GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 + | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS + | GRUB_VGA_IO_MISC_COLOR, GRUB_VGA_IO_MISC_WRITE); + grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC | GRUB_VGA_SR_RESET_SYNC, + GRUB_VGA_SR_RESET); + grub_sm712_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK, + GRUB_VGA_SR_CLOCKING_MODE); + grub_sm712_sr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_SR_MAP_MASK_REGISTER); + grub_sm712_sr_write (0, GRUB_VGA_SR_CHAR_MAP_SELECT); + grub_sm712_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4 + | GRUB_VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING + | GRUB_VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY, + GRUB_VGA_SR_MEMORY_MODE); + + for (i = 0; i < ARRAY_SIZE (sm712_sr_seq1); i++) + grub_sm712_sr_write (sm712_sr_seq1[i], 0x10 + i); + + for (i = 0; i < ARRAY_SIZE (sm712_sr_seq2); i++) + grub_sm712_sr_write (sm712_sr_seq2[i], 0x30 + i); + + /* Undocumented. */ + grub_sm712_sr_write (0x1a, 0x63); + /* Undocumented. */ + grub_sm712_sr_write (0x1a, 0x64); + + grub_sm712_sr_write (GRUB_SM712_SR_TV_CRT_SRAM | GRUB_SM712_SR_TV_ALT_CLOCK + | GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC + | GRUB_SM712_SR_TV_HSYNC, + GRUB_SM712_SR_TV_CONTROL); + + grub_sm712_sr_write (GRUB_SM712_SR_RAM_LUT_NORMAL, GRUB_SM712_SR_RAM_LUT); + + /* Undocumented. */ + grub_sm712_sr_write (0x00, 0x67); + + grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR + | GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK, + GRUB_SM712_SR_CLOCK_CONTROL1); + grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK, + GRUB_SM712_SR_CLOCK_CONTROL2); + + grub_sm712_sr_write (82, GRUB_SM712_SR_VCLK_NUM); + grub_sm712_sr_write (137, GRUB_SM712_SR_VCLK_DENOM); + + grub_sm712_sr_write (9, GRUB_SM712_SR_VCLK2_NUM); + grub_sm712_sr_write (2, GRUB_SM712_SR_VCLK2_DENOM); + /* FIXME */ + grub_sm712_sr_write (0x04, 0x70); + /* FIXME */ + grub_sm712_sr_write (0x45, 0x71); + /* Undocumented */ + grub_sm712_sr_write (0x30, 0x72); + /* Undocumented */ + grub_sm712_sr_write (0x30, 0x73); + /* Undocumented */ + grub_sm712_sr_write (0x40, 0x74); + /* Undocumented */ + grub_sm712_sr_write (0x20, 0x75); + + grub_sm712_sr_write (0xff, GRUB_SM712_SR_POPUP_ICON_LOW); + grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_HIGH_MASK, + GRUB_SM712_SR_POPUP_ICON_HIGH); + grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED, + GRUB_SM712_SR_POPUP_ICON_CTRL); + /* Undocumented */ + grub_sm712_sr_write (0x0, 0x83); + + grub_sm712_sr_write (8, GRUB_SM712_SR_POPUP_ICON_COLOR1); + grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_COLOR2); + grub_sm712_sr_write (0x42, GRUB_SM712_SR_POPUP_ICON_COLOR3); + + /* Undocumented */ + grub_sm712_sr_write (0x3a, 0x87); + + /* Why theese coordinates? */ + grub_sm712_sr_write (0x59, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW); + grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH); + grub_sm712_sr_write (0x44, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW); + grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH); + + grub_sm712_sr_write (RGB332_BLACK, GRUB_SM712_SR_HW_CURSOR_FG_COLOR); + grub_sm712_sr_write (RGB332_WHITE, GRUB_SM712_SR_HW_CURSOR_BG_COLOR); + + /* Undocumented */ + grub_sm712_sr_write (0x3a, 0x8e); + grub_sm712_sr_write (0x3a, 0x8f); + + grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_LOW); + grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_HIGH); + grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_LOW); + grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_HIGH); + + grub_sm712_sr_write (0, GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL); + grub_sm712_sr_write (0x10, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW); + grub_sm712_sr_write (0x08, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH); + grub_sm712_sr_write (0x00, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW); + grub_sm712_sr_write (0x02, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH); + grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT); + grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT); + grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT); + + grub_sm712_sr_write (0x7b, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY); + grub_sm712_sr_write (0xfb, GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY); + grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY); + grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY); + /* Doesn't match documentation? */ + grub_sm712_sr_write (0x97, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY); + grub_sm712_sr_write (0xef, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY); + + grub_sm712_sr_write (0xbf, GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR); + grub_sm712_sr_write (0xdf, GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR); + + grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE); + grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE_ENABLE); + grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_COLOR_COMPARE); + grub_sm712_gr_write (GRUB_VGA_GR_DATA_ROTATE_NOP, GRUB_VGA_GR_DATA_ROTATE); + grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_READ_MAP_REGISTER); + grub_sm712_gr_write (GRUB_VGA_GR_MODE_256_COLOR, GRUB_VGA_GR_MODE); + grub_sm712_gr_write (GRUB_VGA_GR_GR6_MMAP_A0 + | GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6); + grub_sm712_gr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_GR_COLOR_COMPARE_DISABLE); + grub_sm712_gr_write (0xff, GRUB_VGA_GR_BITMASK); + + /* Write palette mapping. */ + for (i = 0; i < 16; i++) + grub_sm712_write_arx (i, i); + + grub_sm712_write_arx (GRUB_VGA_ARX_MODE_ENABLE_256COLOR + | GRUB_VGA_ARX_MODE_GRAPHICS, GRUB_VGA_ARX_MODE); + grub_sm712_write_arx (0, GRUB_VGA_ARX_OVERSCAN); + grub_sm712_write_arx (GRUB_VGA_ALL_PLANES, GRUB_VGA_ARX_COLOR_PLANE_ENABLE); + grub_sm712_write_arx (0, GRUB_VGA_ARX_HORIZONTAL_PANNING); + grub_sm712_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT); + + /* FIXME: compute this generically. */ + { + struct grub_video_hw_config config = { - case 1: - *(volatile grub_uint8_t *) ((char *) framebuffer.ptr - + GRUB_SM712_REG_BASE - + sm712_init[i].addr) = sm712_init[i].val; - break; - case -1: - { - grub_uint8_t val = *(volatile grub_uint8_t *) - ((char *) framebuffer.ptr + GRUB_SM712_REG_BASE - + sm712_init[i].addr); - (void) val; - } - break; - } + .vertical_total = 806, + .vertical_blank_start = 0x300, + .vertical_blank_end = 0, + .vertical_sync_start = 0x303, + .vertical_sync_end = 0x9, + .line_compare = 0x3ff, + .vdisplay_end = 0x300, + .pitch = 0x80, + .horizontal_total = 164, + .horizontal_end = 128, + .horizontal_blank_start = 128, + .horizontal_blank_end = 0, + .horizontal_sync_pulse_start = 133, + .horizontal_sync_pulse_end = 22 + }; + grub_vga_set_geometry (&config, grub_sm712_cr_write); + config.horizontal_sync_pulse_start = 134; + config.horizontal_sync_pulse_end = 21; + config.vertical_sync_start = 0x301; + config.vertical_sync_end = 0x0; + config.line_compare = 0x0ff; + config.vdisplay_end = 0x258; + config.pitch = 0x7f; + grub_vga_set_geometry (&config, grub_sm712_cr_shadow_write); + } + grub_sm712_cr_write (GRUB_VGA_CR_BYTE_PANNING_NORMAL, + GRUB_VGA_CR_BYTE_PANNING); + grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_START); + grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_END); + grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); + grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); + grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_HIGH); + grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_LOW); + grub_sm712_cr_write (GRUB_VGA_CR_UNDERLINE_LOCATION_DWORD_MODE, + GRUB_VGA_CR_UNDERLINE_LOCATION); + grub_sm712_cr_write (GRUB_VGA_CR_MODE_ADDRESS_WRAP + | GRUB_VGA_CR_MODE_BYTE_MODE + | GRUB_VGA_CR_MODE_TIMING_ENABLE + | GRUB_VGA_CR_MODE_NO_CGA + | GRUB_VGA_CR_MODE_NO_HERCULES, + GRUB_VGA_CR_MODE); + + grub_sm712_cr_write (0, GRUB_SM712_CR_OVERFLOW_INTERLACE); + grub_sm712_cr_write (0, GRUB_SM712_CR_INTERLACE_RETRACE); + grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_START); + grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_HIGH); + grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_LOW); + grub_sm712_cr_write (0x80, GRUB_SM712_CR_DDA_CONTROL_LOW); + grub_sm712_cr_write (0x02, GRUB_SM712_CR_DDA_CONTROL_HIGH); + + /* Undocumented */ + grub_sm712_cr_write (0x20, 0x37); + + grub_sm712_cr_write (0, GRUB_SM712_CR_TV_EQUALIZER); + grub_sm712_cr_write (0, GRUB_SM712_CR_TV_SERRATION); + grub_sm712_cr_write (0, GRUB_SM712_CR_HSYNC_CTRL); + + /* Undocumented */ + grub_sm712_cr_write (0x40, 0x3b); + + grub_sm712_cr_write (GRUB_SM712_CR_DEBUG_NONE, GRUB_SM712_CR_DEBUG); + + /* Undocumented */ + grub_sm712_cr_write (0xff, 0x3d); + grub_sm712_cr_write (0x46, 0x3e); + grub_sm712_cr_write (0x91, 0x3f); + + for (i = 0; i < ARRAY_SIZE (dda_lookups); i++) + grub_sm712_write_dda_lookup (i, dda_lookups[i].compare, dda_lookups[i].dda, + dda_lookups[i].vcentering); + + /* Undocumented */ + grub_sm712_cr_write (0, 0x9c); + grub_sm712_cr_write (0, 0x9d); + grub_sm712_cr_write (0, 0x9e); + grub_sm712_cr_write (0, 0x9f); + + grub_sm712_cr_write (0, GRUB_SM712_CR_VCENTERING_OFFSET); + grub_sm712_cr_write (0, GRUB_SM712_CR_HCENTERING_OFFSET); + + grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY + | GRUB_VGA_IO_MISC_UPPER_64K + | GRUB_VGA_IO_MISC_28MHZ + | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS + | GRUB_VGA_IO_MISC_COLOR, + GRUB_VGA_IO_MISC_WRITE); + +#ifndef TEST + /* Undocumented? */ *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c00c) = 0; *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c040) = 0; *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c000) = 0x20000; *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c010) = 0x1020100; +#endif (void) grub_sm712_sr_read (0x16); - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); +#ifndef TEST + err = grub_video_fb_create_render_target_from_pointer (&framebuffer + .render_target, + &framebuffer.mode_info, + framebuffer.ptr); if (err) return err; @@ -203,9 +702,12 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, /* Copy default palette to initialize emulated palette. */ err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); +#endif return err; } +#ifndef TEST + static grub_err_t grub_video_sm712_swap_buffers (void) { @@ -234,7 +736,6 @@ grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info, return GRUB_ERR_NONE; } - static struct grub_video_adapter grub_video_sm712_adapter = { .name = "SM712 Video Driver", @@ -277,3 +778,10 @@ GRUB_MOD_FINI(video_sm712) { grub_video_unregister (&grub_video_sm712_adapter); } +#else +int +main () +{ + grub_video_sm712_setup (1024, 600, 0, 0); +} +#endif diff --git a/video/sm712_init.c b/video/sm712_init.c index 58dbbbbf9..cdb0b7383 100644 --- a/video/sm712_init.c +++ b/video/sm712_init.c @@ -1,540 +1,14 @@ /* Following sequence is a capture of sm712 initialisation sequence. */ -static struct -{ - int directive; - grub_uint32_t addr; - grub_uint32_t val; -} sm712_init[] = -{ - {1, 0x3c4, 0x21}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x62}, - {1, 0x3c5, 0x7a}, - {1, 0x3c4, 0x6a}, - {1, 0x3c5, 0x16}, - {1, 0x3c4, 0x6b}, - {1, 0x3c5, 0x2}, - {1, 0x3c6, 0x0}, - {1, 0x3c4, 0x0}, - {1, 0x3c5, 0x1}, - {1, 0x3c2, 0xeb}, - {1, 0x3c4, 0x0}, - {1, 0x3c5, 0x3}, - {1, 0x3c4, 0x1}, - {1, 0x3c5, 0x1}, - {1, 0x3c4, 0x2}, - {1, 0x3c5, 0xf}, - {1, 0x3c4, 0x3}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x4}, - {1, 0x3c5, 0xe}, - {1, 0x3c4, 0x10}, - {1, 0x3c5, 0xc8}, - {1, 0x3c4, 0x11}, - {1, 0x3c5, 0x40}, - {1, 0x3c4, 0x12}, - {1, 0x3c5, 0x14}, - {1, 0x3c4, 0x13}, - {1, 0x3c5, 0x60}, - {1, 0x3c4, 0x14}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x15}, - {1, 0x3c5, 0xa}, - {1, 0x3c4, 0x16}, - {1, 0x3c5, 0x92}, - {1, 0x3c4, 0x17}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x18}, - {1, 0x3c5, 0x51}, - {1, 0x3c4, 0x19}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x1a}, - {1, 0x3c5, 0x1}, - {1, 0x3c4, 0x1b}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x1c}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x1d}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x1e}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x1f}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x20}, - {1, 0x3c5, 0xc4}, - {1, 0x3c4, 0x21}, - {1, 0x3c5, 0x30}, - {1, 0x3c4, 0x22}, - {1, 0x3c5, 0x2}, - {1, 0x3c4, 0x23}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x24}, - {1, 0x3c5, 0x1}, - {1, 0x3c4, 0x30}, - {1, 0x3c5, 0x28}, - {1, 0x3c4, 0x31}, - {1, 0x3c5, 0x3}, - {1, 0x3c4, 0x32}, - {1, 0x3c5, 0x24}, - {1, 0x3c4, 0x33}, - {1, 0x3c5, 0x9}, - {1, 0x3c4, 0x34}, - {1, 0x3c5, 0xc0}, - {1, 0x3c4, 0x35}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x36}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x37}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x38}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x39}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x3a}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x3b}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x3c}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x3d}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x3e}, - {1, 0x3c5, 0x3}, - {1, 0x3c4, 0x3f}, - {1, 0x3c5, 0xff}, - {1, 0x3c4, 0x40}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x41}, - {1, 0x3c5, 0xfc}, - {1, 0x3c4, 0x42}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x43}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x44}, - {1, 0x3c5, 0x20}, - {1, 0x3c4, 0x45}, - {1, 0x3c5, 0x18}, - {1, 0x3c4, 0x46}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x47}, - {1, 0x3c5, 0xfc}, - {1, 0x3c4, 0x48}, - {1, 0x3c5, 0x20}, - {1, 0x3c4, 0x49}, - {1, 0x3c5, 0xc}, - {1, 0x3c4, 0x4a}, - {1, 0x3c5, 0x44}, - {1, 0x3c4, 0x4b}, - {1, 0x3c5, 0x20}, - {1, 0x3c4, 0x4c}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x4d}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x4e}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x4f}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x50}, - {1, 0x3c5, 0x6}, - {1, 0x3c4, 0x51}, - {1, 0x3c5, 0x68}, - {1, 0x3c4, 0x52}, - {1, 0x3c5, 0xa7}, - {1, 0x3c4, 0x53}, - {1, 0x3c5, 0x7f}, - {1, 0x3c4, 0x54}, - {1, 0x3c5, 0x83}, - {1, 0x3c4, 0x55}, - {1, 0x3c5, 0x24}, - {1, 0x3c4, 0x56}, - {1, 0x3c5, 0xff}, - {1, 0x3c4, 0x57}, - {1, 0x3c5, 0x3}, - {1, 0x3c4, 0x58}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x59}, - {1, 0x3c5, 0x60}, - {1, 0x3c4, 0x5a}, - {1, 0x3c5, 0x59}, - {1, 0x3c4, 0x5b}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x5c}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x5d}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x5e}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x5f}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x60}, - {1, 0x3c5, 0x1}, - {1, 0x3c4, 0x61}, - {1, 0x3c5, 0x80}, - {1, 0x3c4, 0x63}, - {1, 0x3c5, 0x1a}, - {1, 0x3c4, 0x64}, - {1, 0x3c5, 0x1a}, - {1, 0x3c4, 0x65}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x66}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x67}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x68}, - {1, 0x3c5, 0x50}, - {1, 0x3c4, 0x69}, - {1, 0x3c5, 0x3}, - {1, 0x3c4, 0x6c}, - {1, 0x3c5, 0x52}, - {1, 0x3c4, 0x6d}, - {1, 0x3c5, 0x89}, - {1, 0x3c4, 0x6e}, - {1, 0x3c5, 0x9}, - {1, 0x3c4, 0x6f}, - {1, 0x3c5, 0x2}, - {1, 0x3c4, 0x70}, - {1, 0x3c5, 0x4}, - {1, 0x3c4, 0x71}, - {1, 0x3c5, 0x45}, - {1, 0x3c4, 0x72}, - {1, 0x3c5, 0x30}, - {1, 0x3c4, 0x73}, - {1, 0x3c5, 0x30}, - {1, 0x3c4, 0x74}, - {1, 0x3c5, 0x40}, - {1, 0x3c4, 0x75}, - {1, 0x3c5, 0x20}, - {1, 0x3c4, 0x80}, - {1, 0x3c5, 0xff}, - {1, 0x3c4, 0x81}, - {1, 0x3c5, 0x7}, - {1, 0x3c4, 0x82}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x83}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x84}, - {1, 0x3c5, 0x8}, - {1, 0x3c4, 0x85}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x86}, - {1, 0x3c5, 0x42}, - {1, 0x3c4, 0x87}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x88}, - {1, 0x3c5, 0x59}, - {1, 0x3c4, 0x89}, - {1, 0x3c5, 0x2}, - {1, 0x3c4, 0x8a}, - {1, 0x3c5, 0x44}, - {1, 0x3c4, 0x8b}, - {1, 0x3c5, 0x2}, - {1, 0x3c4, 0x8c}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x8d}, - {1, 0x3c5, 0xff}, - {1, 0x3c4, 0x8e}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x8f}, - {1, 0x3c5, 0x3a}, - {1, 0x3c4, 0x90}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x91}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x92}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0x93}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0xa0}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0xa1}, - {1, 0x3c5, 0x10}, - {1, 0x3c4, 0xa2}, - {1, 0x3c5, 0x8}, - {1, 0x3c4, 0xa3}, - {1, 0x3c5, 0x0}, - {1, 0x3c4, 0xa4}, - {1, 0x3c5, 0x2}, - {1, 0x3c4, 0xa5}, - {1, 0x3c5, 0xed}, - {1, 0x3c4, 0xa6}, - {1, 0x3c5, 0xed}, - {1, 0x3c4, 0xa7}, - {1, 0x3c5, 0xed}, - {1, 0x3c4, 0xa8}, - {1, 0x3c5, 0x7b}, - {1, 0x3c4, 0xa9}, - {1, 0x3c5, 0xfb}, - {1, 0x3c4, 0xaa}, - {1, 0x3c5, 0xff}, - {1, 0x3c4, 0xab}, - {1, 0x3c5, 0xff}, - {1, 0x3c4, 0xac}, - {1, 0x3c5, 0x97}, - {1, 0x3c4, 0xad}, - {1, 0x3c5, 0xef}, - {1, 0x3c4, 0xae}, - {1, 0x3c5, 0xbf}, - {1, 0x3c4, 0xaf}, - {1, 0x3c5, 0xdf}, - {1, 0x3ce, 0x0}, - {1, 0x3cf, 0x0}, - {1, 0x3ce, 0x1}, - {1, 0x3cf, 0x0}, - {1, 0x3ce, 0x2}, - {1, 0x3cf, 0x0}, - {1, 0x3ce, 0x3}, - {1, 0x3cf, 0x0}, - {1, 0x3ce, 0x4}, - {1, 0x3cf, 0x0}, - {1, 0x3ce, 0x5}, - {1, 0x3cf, 0x40}, - {1, 0x3ce, 0x6}, - {1, 0x3cf, 0x5}, - {1, 0x3ce, 0x7}, - {1, 0x3cf, 0xf}, - {1, 0x3ce, 0x8}, - {1, 0x3cf, 0xff}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x0}, - {-1, 0x3c1, 0x3e}, - {1, 0x3c0, 0x0}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x1}, - {-1, 0x3c1, 0x3b}, - {1, 0x3c0, 0x1}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x2}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0x2}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x3}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0x3}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x4}, - {-1, 0x3c1, 0x3b}, - {1, 0x3c0, 0x4}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x5}, - {-1, 0x3c1, 0x2f}, - {1, 0x3c0, 0x5}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x6}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0x6}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x7}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0x7}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x8}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0x8}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x9}, - {-1, 0x3c1, 0x3d}, - {1, 0x3c0, 0x9}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0xa}, - {-1, 0x3c1, 0x1f}, - {1, 0x3c0, 0xa}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0xb}, - {-1, 0x3c1, 0x1f}, - {1, 0x3c0, 0xb}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0xc}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0xc}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0xd}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0xd}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0xe}, - {-1, 0x3c1, 0x3f}, - {1, 0x3c0, 0xe}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0xf}, - {-1, 0x3c1, 0x2e}, - {1, 0x3c0, 0xf}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x10}, - {-1, 0x3c1, 0x0}, - {1, 0x3c0, 0x41}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x11}, - {-1, 0x3c1, 0x0}, - {1, 0x3c0, 0x0}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x12}, - {-1, 0x3c1, 0x0}, - {1, 0x3c0, 0xf}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x13}, - {-1, 0x3c1, 0x0}, - {1, 0x3c0, 0x0}, - {-1, 0x3da, 0x5}, - {1, 0x3c0, 0x14}, - {-1, 0x3c1, 0x0}, - {1, 0x3c0, 0x0}, - {1, 0x3d4, 0x0}, - {1, 0x3d5, 0xa3}, - {1, 0x3d4, 0x1}, - {1, 0x3d5, 0x7f}, - {1, 0x3d4, 0x2}, - {1, 0x3d5, 0x7f}, - {1, 0x3d4, 0x3}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x4}, - {1, 0x3d5, 0x85}, - {1, 0x3d4, 0x5}, - {1, 0x3d5, 0x16}, - {1, 0x3d4, 0x6}, - {1, 0x3d5, 0x24}, - {1, 0x3d4, 0x7}, - {1, 0x3d5, 0xf5}, - {1, 0x3d4, 0x8}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x9}, - {1, 0x3d5, 0x60}, - {1, 0x3d4, 0xa}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0xb}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0xc}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0xd}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0xe}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0xf}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x10}, - {1, 0x3d5, 0x3}, - {1, 0x3d4, 0x11}, - {1, 0x3d5, 0x9}, - {1, 0x3d4, 0x12}, - {1, 0x3d5, 0xff}, - {1, 0x3d4, 0x13}, - {1, 0x3d5, 0x80}, - {1, 0x3d4, 0x14}, - {1, 0x3d5, 0x40}, - {1, 0x3d4, 0x15}, - {1, 0x3d5, 0xff}, - {1, 0x3d4, 0x16}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x17}, - {1, 0x3d5, 0xe3}, - {1, 0x3d4, 0x18}, - {1, 0x3d5, 0xff}, - {1, 0x3d4, 0x30}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x31}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x32}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x33}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x34}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x35}, - {1, 0x3d5, 0x80}, - {1, 0x3d4, 0x36}, - {1, 0x3d5, 0x2}, - {1, 0x3d4, 0x37}, - {1, 0x3d5, 0x20}, - {1, 0x3d4, 0x38}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x39}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x3a}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x3b}, - {1, 0x3d5, 0x40}, - {1, 0x3d4, 0x3c}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x3d}, - {1, 0x3d5, 0xff}, - {1, 0x3d4, 0x3e}, - {1, 0x3d5, 0x46}, - {1, 0x3d4, 0x3f}, - {1, 0x3d5, 0x91}, - {1, 0x3d4, 0x40}, - {1, 0x3d5, 0xa3}, - {1, 0x3d4, 0x41}, - {1, 0x3d5, 0x7f}, - {1, 0x3d4, 0x42}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x43}, - {1, 0x3d5, 0x86}, - {1, 0x3d4, 0x44}, - {1, 0x3d5, 0x15}, - {1, 0x3d4, 0x45}, - {1, 0x3d5, 0x24}, - {1, 0x3d4, 0x46}, - {1, 0x3d5, 0xff}, - {1, 0x3d4, 0x47}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x48}, - {1, 0x3d5, 0x1}, - {1, 0x3d4, 0x49}, - {1, 0x3d5, 0x7}, - {1, 0x3d4, 0x4a}, - {1, 0x3d5, 0xe5}, - {1, 0x3d4, 0x4b}, - {1, 0x3d5, 0x20}, - {1, 0x3d4, 0x4c}, - {1, 0x3d5, 0x7f}, - {1, 0x3d4, 0x4d}, - {1, 0x3d5, 0x57}, - {1, 0x3d4, 0x90}, - {1, 0x3d5, 0x55}, - {1, 0x3d4, 0x91}, - {1, 0x3d5, 0xd5}, - {1, 0x3d4, 0x92}, - {1, 0x3d5, 0x5d}, - {1, 0x3d4, 0x93}, - {1, 0x3d5, 0xdd}, - {1, 0x3d4, 0x94}, - {1, 0x3d5, 0x86}, - {1, 0x3d4, 0x95}, - {1, 0x3d5, 0x17}, - {1, 0x3d4, 0x96}, - {1, 0x3d5, 0x8e}, - {1, 0x3d4, 0x97}, - {1, 0x3d5, 0xaa}, - {1, 0x3d4, 0x98}, - {1, 0x3d5, 0x8a}, - {1, 0x3d4, 0x99}, - {1, 0x3d5, 0xa3}, - {1, 0x3d4, 0x9a}, - {1, 0x3d5, 0xde}, - {1, 0x3d4, 0x9b}, - {1, 0x3d5, 0xab}, - {1, 0x3d4, 0x9c}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x9d}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x9e}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0x9f}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0xa0}, - {1, 0x3d5, 0x2}, - {1, 0x3d4, 0xa1}, - {1, 0x3d5, 0x2}, - {1, 0x3d4, 0xa2}, - {1, 0x3d5, 0x2}, - {1, 0x3d4, 0xa3}, - {1, 0x3d5, 0x15}, - {1, 0x3d4, 0xa4}, - {1, 0x3d5, 0x2}, - {1, 0x3d4, 0xa5}, - {1, 0x3d5, 0x6}, - {1, 0x3d4, 0xa6}, - {1, 0x3d5, 0x0}, - {1, 0x3d4, 0xa7}, - {1, 0x3d5, 0x0}, - {1, 0x3c2, 0x67}, -}; +static grub_uint8_t sm712_sr_seq1[] = + { 0xc8, 0x40, 0x14, 0x60, 0x0, 0xa, 0x92, 0x0, + 0x51, 0x00, 0x01, 0x00, 0x0, 0x0, 0x00, 0x0, + 0xc4, 0x30, 0x02, 0x00, 0x1 }; + +static grub_uint8_t sm712_sr_seq2[] = + { 0x28, 0x03, 0x24, 0x09, 0xc0, 0x3a, 0x3a, 0x3a, + 0x3a, 0x3a, 0x3a, 0x3a, 0x00, 0x00, 0x03, 0xff, + 0x00, 0xfc, 0x00, 0x00, 0x20, 0x18, 0x00, 0xfc, + 0x20, 0x0c, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3a, + 0x06, 0x68, 0xa7, 0x7f, 0x83, 0x24, 0xff, 0x03, + 0x00, 0x60, 0x59, 0x3a, 0x3a, 0x00, 0x00, 0x3a, + 0x01, 0x80 }; From d04b9414a8ab42944596950514f6353c8734eb60 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 11 Aug 2010 04:25:56 +0200 Subject: [PATCH 497/503] * kern/i386/qemu/init.c (grub_qemu_init_cirrus): Fix compilation error. --- ChangeLog | 4 ++++ kern/i386/qemu/init.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5d9d7a759..dae79ab7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-11 Vladimir Serbinenko + + * kern/i386/qemu/init.c (grub_qemu_init_cirrus): Fix compilation error. + 2010-08-11 Vladimir Serbinenko Remove the dump of sm712 initialisation sequence. diff --git a/kern/i386/qemu/init.c b/kern/i386/qemu/init.c index bd12953df..054dfa86b 100644 --- a/kern/i386/qemu/init.c +++ b/kern/i386/qemu/init.c @@ -121,11 +121,11 @@ grub_qemu_init_cirrus (void) GRUB_VGA_SR_MAP_MASK_REGISTER); grub_vga_cr_write (15, GRUB_VGA_CR_CELL_HEIGHT); - grub_vga_cr_write (79, GRUB_VGA_CR_WIDTH); + grub_vga_cr_write (79, GRUB_VGA_CR_HORIZ_END); grub_vga_cr_write (40, GRUB_VGA_CR_PITCH); int vert = 25 * 16; - grub_vga_cr_write (vert & 0xff, GRUB_VGA_CR_HEIGHT); + grub_vga_cr_write (vert & 0xff, GRUB_VGA_CR_VDISPLAY_END); grub_vga_cr_write (((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT) & GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK) | ((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT) From 79a6ba6101bfbcab861d0e2cb9bcc4552b042cd6 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Wed, 11 Aug 2010 13:24:37 +0200 Subject: [PATCH 498/503] 2010-08-11 Yves Blusseau * .bzrignore: add grub-macho2img --- .bzrignore | 1 + ChangeLog | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.bzrignore b/.bzrignore index 32b96b154..26558087a 100644 --- a/.bzrignore +++ b/.bzrignore @@ -40,6 +40,7 @@ grub-fstest grub_fstest_init.c grub_fstest_init.h grub-install +grub-macho2img grub-mk* grub-pbkdf2 grub-pe2elf diff --git a/ChangeLog b/ChangeLog index dae79ab7e..005428b5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-11 Yves Blusseau + + * .bzrignore: add grub-macho2img + 2010-08-11 Vladimir Serbinenko * kern/i386/qemu/init.c (grub_qemu_init_cirrus): Fix compilation error. From 681440aa5bda1d517158d7f1fd821971419b9ea8 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 12 Aug 2010 20:45:55 +0530 Subject: [PATCH 499/503] fix bad color name handling --- include/grub/normal.h | 2 +- normal/color.c | 25 ++++++++++++++----------- normal/main.c | 4 ++++ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/grub/normal.h b/include/grub/normal.h index a33e42e61..2a0298bc6 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -73,7 +73,7 @@ grub_err_t grub_normal_print_device_info (const char *name); /* Defined in `color.c'. */ 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); +int grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); /* Defined in `menu_text.c'. */ void grub_wait_after_message (void); diff --git a/normal/color.c b/normal/color.c index bae082911..a16d1c2f9 100644 --- a/normal/color.c +++ b/normal/color.c @@ -56,22 +56,23 @@ parse_color_name (grub_uint8_t *ret, char *name) return -1; } -void -grub_parse_color_name_pair (grub_uint8_t *ret, const char *name) +int +grub_parse_color_name_pair (grub_uint8_t *color, const char *name) { + int result = 1; grub_uint8_t fg, bg; char *fg_name, *bg_name; /* nothing specified by user */ if (name == NULL) - return; + return result; fg_name = grub_strdup (name); if (fg_name == NULL) { /* "out of memory" message was printed by grub_strdup() */ grub_wait_after_message (); - return; + return result; } bg_name = grub_strchr (fg_name, '/'); @@ -97,10 +98,12 @@ grub_parse_color_name_pair (grub_uint8_t *ret, const char *name) goto free_and_return; } - *ret = (bg << 4) | fg; + *color = (bg << 4) | fg; + result = 0; free_and_return: grub_free (fg_name); + return result; } static grub_uint8_t color_normal, color_highlight; @@ -122,10 +125,10 @@ set_colors (void) /* 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_env_write_color_normal (struct grub_env_var *var, const char *val) { - grub_parse_color_name_pair (&color_normal, val); + if (grub_parse_color_name_pair (&color_normal, val)) + return 0; set_colors (); @@ -134,10 +137,10 @@ grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)), /* 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_env_write_color_highlight (struct grub_env_var *var, const char *val) { - grub_parse_color_name_pair (&color_highlight, val); + if (grub_parse_color_name_pair (&color_highlight, val)) + return 0; set_colors (); diff --git a/normal/main.c b/normal/main.c index 5df889466..49658fd24 100644 --- a/normal/main.c +++ b/normal/main.c @@ -705,6 +705,10 @@ GRUB_MOD_INIT(normal) /* Preserve hooks after context changes. */ grub_env_export ("color_normal"); grub_env_export ("color_highlight"); + + /* Set default color names. */ + grub_env_set ("color_normal", "white/black"); + grub_env_set ("color_highlight", "black/white"); } GRUB_MOD_FINI(normal) From f3710e088ce80dcc038b6c890191f7646461a101 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 14 Aug 2010 16:53:25 +0200 Subject: [PATCH 500/503] 2010-08-14 Robert Millan * kern/emu/misc.c (grub_find_zpool_from_dir): Abort function if filesystem is not ZFS. --- ChangeLog | 5 +++++ kern/emu/misc.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3703337d8..b88eae46f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-14 Robert Millan + + * kern/emu/misc.c (grub_find_zpool_from_dir): Abort function if + filesystem is not ZFS. + 2010-08-12 BVK Chaitanya Fix for misspelled color names defaulting to black/black (bug diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 760471ebb..29be87720 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -288,6 +288,9 @@ grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) if (statfs (dir, &mnt) != 0) return; + if (strcmp (mnt.f_fstypename, "zfs") != 0) + return; + *poolname = xstrdup (mnt.f_mntfromname); slash = strchr (*poolname, '/'); From 729a0f2e0c59b342292ceb47fbc014f00c409524 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 15 Aug 2010 22:48:23 +0200 Subject: [PATCH 501/503] 2010-08-15 Robert Millan * kern/emu/misc.c (grub_get_libzfs_handle): Handle libzfs_init() errors. * kern/emu/getroot.c (find_root_device_from_libzfs): Handle grub_get_libzfs_handle() errors. --- ChangeLog | 7 +++++++ kern/emu/getroot.c | 7 ++++++- kern/emu/misc.c | 4 +++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b88eae46f..b662428bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-08-15 Robert Millan + + * kern/emu/misc.c (grub_get_libzfs_handle): Handle libzfs_init() + errors. + * kern/emu/getroot.c (find_root_device_from_libzfs): Handle + grub_get_libzfs_handle() errors. + 2010-08-14 Robert Millan * kern/emu/misc.c (grub_find_zpool_from_dir): Abort function if diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 321b33bb3..c0a10d22b 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -188,11 +188,16 @@ find_root_device_from_libzfs (const char *dir) { zpool_handle_t *zpool; + libzfs_handle_t *libzfs; nvlist_t *nvlist; nvlist_t **nvlist_array; unsigned int nvlist_count; - zpool = zpool_open (grub_get_libzfs_handle (), poolname); + libzfs = grub_get_libzfs_handle (); + if (! libzfs) + return NULL; + + zpool = zpool_open (libzfs, poolname); nvlist = zpool_get_config (zpool, NULL); if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0) diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 29be87720..82f579616 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -268,7 +268,9 @@ grub_get_libzfs_handle (void) if (! __libzfs_handle) { __libzfs_handle = libzfs_init (); - atexit (fini_libzfs); + + if (__libzfs_handle) + atexit (fini_libzfs); } return __libzfs_handle; From 9da94e0576bb2f0f5d24ab8972a5a4b6de239d8f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 18 Aug 2010 11:08:00 +0100 Subject: [PATCH 502/503] * acinclude.m4 (grub_ASM_USCORE): Use a more accurate grep pattern, to avoid false positives with some assemblers that output things like "someprefix_func" as part of their output. --- ChangeLog | 6 ++++++ acinclude.m4 | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b662428bc..d5e67639e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-08-18 Colin Watson + + * acinclude.m4 (grub_ASM_USCORE): Use a more accurate grep pattern, + to avoid false positives with some assemblers that output things + like "someprefix_func" as part of their output. + 2010-08-15 Robert Millan * kern/emu/misc.c (grub_get_libzfs_handle): Handle libzfs_init() diff --git a/acinclude.m4 b/acinclude.m4 index 72483b5d0..49760d5f0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -38,6 +38,7 @@ 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_REQUIRE([AC_PROG_EGREP]) AC_MSG_CHECKING([if C symbols get an underscore after compilation]) AC_CACHE_VAL(grub_cv_asm_uscore, [cat > conftest.c <<\EOF @@ -56,7 +57,7 @@ else AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) fi -if grep _func conftest.s >/dev/null 2>&1; then +if $EGREP '(^|[^_[:alnum]])_func' conftest.s >/dev/null 2>&1; then grub_cv_asm_uscore=yes else grub_cv_asm_uscore=no From 51f1f5afab3f3e581c54b78af0b91780c4f78b68 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 18 Aug 2010 11:15:08 +0100 Subject: [PATCH 503/503] * configure.ac: Move AM_INIT_AUTOMAKE after AC_CANONICAL_TARGET to fix warnings from Autoconf. --- ChangeLog | 5 +++++ configure.ac | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d5e67639e..bf1a0cfbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-18 Colin Watson + + * configure.ac: Move AM_INIT_AUTOMAKE after AC_CANONICAL_TARGET to + fix warnings from Autoconf. + 2010-08-18 Colin Watson * acinclude.m4 (grub_ASM_USCORE): Use a more accurate grep pattern, diff --git a/configure.ac b/configure.ac index 19d782609..4091b4fa2 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,6 @@ dnl type. AC_INIT([GRUB],[1.98],[bug-grub@gnu.org]) -AM_INIT_AUTOMAKE() AC_PREREQ(2.60) AC_CONFIG_SRCDIR([include/grub/dl.h]) AC_CONFIG_HEADER([config.h]) @@ -41,6 +40,8 @@ AC_CONFIG_HEADER([config.h]) AC_CANONICAL_HOST AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE() + # Program name transformations AC_ARG_PROGRAM