patch grub EFI setjmp in IA32
hi, In IA32 application function parameter is passed on stack but not register, on grub_setjmp funciton, env is pushed on stack, but not eax register.Caller is responsible to push parameter on the stack and after function call pop the stack. Here is the patch for setjmp.S in IA32 EFI, any suggestion is welcome. Thanks bibo,mao --- grub-1.94.org/normal/i386/setjmp.S 2004-04-04 21:46:03.0 +0800 +++ grub-1.94/normal/i386/setjmp.S 2006-08-03 11:00:02.0 +0800 @@ -27,11 +27,13 @@ * int grub_setjmp (grub_jmp_buf env) */ FUNCTION(grub_setjmp) + popl%ecx + popl%eax + pushl %eax movl%ebx, 0(%eax) /* EBX */ movl%esi, 4(%eax) /* ESI */ movl%edi, 8(%eax) /* EDI */ movl%ebp, 12(%eax) /* EBP */ - popl%ecx movl%esp, 16(%eax) /* ESP */ movl%ecx, 20(%eax) /* EIP */ xorl%eax, %eax @@ -42,6 +44,11 @@ FUNCTION(grub_setjmp) * int grub_longjmp (grub_jmp_buf env, int val) */ FUNCTION(grub_longjmp) + popl%eax/* skip return address */ + popl%edx + popl%eax + pushl %eax + pushl %edx movl0(%eax), %ebx movl4(%eax), %esi movl8(%eax), %edi ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
EFI disk probing problem
hi, My hard disk is MBR partition type, there is FAT partition in my logical partition, bootloader grub.efi is in this partition. When grub efi bootloader starts up, it cannot probe my hard disk. It is because that parent device_path of current logical partition is extended partition, but not my hard disk's device path. Here I wrote one patch to solve this problem, I discarded the device whose type is not GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, added devices whose type is GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE as hard-disk or cdrom disk. Any suggestion is welcome:) I sent email to grub mailing list, but there is no response, I do not know why. thanks bibo,mao --- grub-1.94.org/disk/efi/efidisk.c2006-05-01 05:09:37.0 +0800 +++ grub-1.94/disk/efi/efidisk.c2006-07-26 13:00:09.0 +0800 @@ -87,6 +87,51 @@ find_last_device_path (const grub_efi_de return p; } +static int compare_ancestor_path(const grub_efi_device_path_t *parent, +const grub_efi_device_path_t *dp2) +{ + if (! parent || ! dp2) + /* Return non-zero. */ + return 1; + + while (1){ + grub_efi_uint8_t type1, type2; + grub_efi_uint8_t subtype1, subtype2; + grub_efi_uint16_t len1, len2; + int ret; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH(parent)) + break; + + type1 = GRUB_EFI_DEVICE_PATH_TYPE (parent); + type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2); + + if (type1 != type2) + return (int) type2 - (int) type1; + + subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (parent); + subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2); + + if (subtype1 != subtype2) + return (int) subtype1 - (int) subtype2; + + len1 = GRUB_EFI_DEVICE_PATH_LENGTH (parent); + len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2); + + if (len1 != len2) + return (int) len1 - (int) len2; + + ret = grub_memcmp (parent, dp2, len1); + if (ret != 0) + return ret; + + parent = (grub_efi_device_path_t *) ((char *) parent + len1); + dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); + } + + return 0; +} + /* Compare device paths. */ static int compare_device_paths (const grub_efi_device_path_t *dp1, @@ -301,109 +346,34 @@ add_device (struct grub_efidisk_data **d } /* Name the devices. */ -static void -name_devices (struct grub_efidisk_data *devices) -{ - struct grub_efidisk_data *d; - - /* First, identify devices by media device paths. */ - for (d = devices; d; d = d->next) -{ - grub_efi_device_path_t *dp; +static void name_devices (struct grub_efidisk_data *devices){ + struct grub_efidisk_data *d; - dp = d->last_device_path; - if (! dp) - continue; - - if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) - { - int is_hard_drive = 0; - - switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp)) - { - case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: - is_hard_drive = 1; - /* Fall through by intention. */ - case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: - { - struct grub_efidisk_data *parent; - - parent = find_parent_device (devices, d); - if (parent) - { - if (is_hard_drive) - { -#if 0 - grub_printf ("adding a hard drive by a partition: "); - grub_print_device_path (parent->device_path); -#endif - add_device (&hd_devices, parent); - } - else - { -#if 0 - grub_printf ("adding a cdrom by a partition: "); - grub_print_device_path (parent->device_path); -#endif - add_device (&cd_devices, parent); - } - - /* Mark the parent as used. */ - parent->last_device_path = 0; - } - } - /* Mark itself as used. */ - d->last_device_path = 0; - break; - - default: - /* For now, ignore the others. */ - break; - } - } -} - - /* Let's see what can be added more. */ - for (d = devices; d; d = d->next) -{ - grub_efi_device_path_t *dp; - grub_efi_block_io_media_t *m; - - dp = d->last_device_path; - if (! dp) - continue; - - m = d->block_io->media; - if (m->logical_partition) - { - /* Only one partition in a non-media device. Assume tha
Re: EFI disk probing problem
Hi, Sorry for late reply because of some other issues, here is my device mapping table, I describe it in tree format blk1(floppy) blkA(BlockDevice cd-rom) blkB(BlockDevice harddisk) |- blk2 (primary partition) |- blk3 (primary partition) |- blk4 (primary partition) |- blk5 (extended partition) | blk6 (logical partition) | blk7 (logical partition) | blk0 (logical partition) | blk8 (logical partition) | blk9 (logical partition) my harddisk is MBR partition type, blk0 is my grub FAT partition. EFI regards all partitions and disk node as block device, only that its type is different, parition block device's subtype is GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, but disk nod is not, harddisk/cdrom nod type is GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE, floppy disk type is GRUB_EFI_ACPI_DEVICE_PATH_TYPE. In order to find root disk, current method is to find harddisk type device's parent device, parent device of block0 is blk5, so it will reagards blk5 as one block device. Actually it is only one extended partition. My patch discards all partition device(GRUB_EFI_MEDIA_DEVICE_PATH_TYPE). thanks bibo,mao blk1:Floppy - Alias (null) Acpi(PNP0A03,0)/Pci(1F|0)/Acpi(PNP0604,0) blkA:BlockDevice - Alias (null) Acpi(PNP0A03,0)/Pci(1F|1)/Ata(Primary,Master) blkB:BlockDevice - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master) blk2:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part1,SigA3A3A3A3) blk3:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part2,SigA3A3A3A3) blk4:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part3,SigA3A3A3A3) blk5:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part4,SigA3A3A3A3) blk6:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part4,SigA3A3A3A3)/HD(Part1,Sig) blk7:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part4,SigA3A3A3A3)/HD(Part2,Sig) blk0:HardDisk - Alias hd31a4d fs0 Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part4,SigA3A3A3A3)/HD(Part3,Sig) blk8:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part4,SigA3A3A3A3)/HD(Part4,Sig) blk9:HardDisk - Alias (null) Acpi(PNP0A03,0)/Pci(1F|2)/Ata(Primary,Master)/HD(Part4,SigA3A3A3A3)/HD(Part5,Sig) Yoshinori K. Okuji wrote: On Saturday 12 August 2006 18:09, Johan Rydberg wrote: > "Yoshinori K. Okuji" <[EMAIL PROTECTED]> writes: > > I don't remember precisely, but I think I only added disk devices but not > > partition devices. On your system, don't disk devices as well as > > partition devices get enumerated? > > I'm not 100% sure about this, but I think EFI does not have to add a > disk device node if there is only a single logical partition on the > disk. Maybe you are right. I hope Mao will comment on this. Okuji ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
grub2 64bit system compatible
Hi, The following is grub2 64-bit system compatible patch, in 64-bit system unsigned long is defined as 64-bit, but not 32-bit. This patch modify this point. Thanks bibo,mao --- grub2/fs/fat.c 2006-06-04 23:56:54.0 +0800 +++ grub2.new/fs/fat.c 2006-09-07 16:49:50.0 +0800 @@ -243,7 +243,7 @@ grub_fat_mount (grub_disk_t disk) else { /* FAT12 or FAT16. */ - data->root_cluster = ~0UL; + data->root_cluster = 0x; if (data->num_clusters <= 4085 + 2) { @@ -297,7 +297,7 @@ grub_fat_mount (grub_disk_t disk) /* Start from the root directory. */ data->file_cluster = data->root_cluster; - data->cur_cluster_num = ~0UL; + data->cur_cluster_num = 0x; data->attr = GRUB_FAT_ATTR_DIRECTORY; return data; @@ -322,7 +322,7 @@ grub_fat_read_data (grub_disk_t disk, st /* This is a special case. FAT12 and FAT16 doesn't have the root directory in clusters. */ - if (data->file_cluster == ~0UL) + if (data->file_cluster == 0x) { size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset; if (size > len) @@ -618,7 +618,7 @@ grub_fat_find_dir (grub_disk_t disk, str data->file_size = grub_le_to_cpu32 (dir.file_size); data->file_cluster = ((grub_le_to_cpu16 (dir.first_cluster_high) << 16) | grub_le_to_cpu16 (dir.first_cluster_low)); - data->cur_cluster_num = ~0UL; + data->cur_cluster_num = 0x; return dirp; } --- grub2/disk/loopback.c 2006-06-04 23:56:54.0 +0800 +++ grub2.new/disk/loopback.c 2006-09-07 16:32:06.0 +0800 @@ -179,7 +179,7 @@ grub_loopback_open (const char *name, gr /* Use the filesize for the disk size, round up to a complete sector. */ disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1) / GRUB_DISK_SECTOR_SIZE); - disk->id = (int) dev; + disk->id = (unsigned long) dev; disk->has_partitions = dev->has_partitions; disk->data = file; --- grub2/include/grub/efi/api.h2006-05-28 05:09:25.0 +0800 +++ grub2.new/include/grub/efi/api.h2006-09-07 16:32:06.0 +0800 @@ -167,7 +168,7 @@ typedef grub_uint16_t grub_efi_char16_t; typedef grub_efi_intn_t grub_efi_status_t; #define GRUB_EFI_ERROR_CODE(value) \ - ((1 << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) + ((0x1L << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) #define GRUB_EFI_WARNING_CODE(value)(value) ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: Grub for ia64
It is great!!!, I will test on my IA64 box tommorrow. And I have few minor comments like this. whether kern/ia64/efi/init.c can be common for all architectures of efi platform, only grub_arch_sync_caches is different, this function can be placed on arch specific place. Function find_mmap_size can fit for all architectures. why write different grub_efi_allocate_pages/grub_efi_free_boot_pages, we can modify these two functions to fit for all architecture EFI platform. thanks bibo,mao [EMAIL PROTECTED] wrote: Hi this is a port of grub2 to ia64. ia64 systems (itanium) are EFI based so this port reuse existing EFI infrastructure. I have made 4 patches: efi64.diffs: fix a 64 bits issue of efi/api.h fat.diffs: fix 64bits issues and make filename match case insensitive. [I think most 64 bits issues have already been reported recently and independently by the mail grub2 64bit system compatible] ia64.diffs: ia64 specific files modules.diffs: currently the ia64 port cannot load modules. This patch makes slight changes so that grub can be completly prelinked without removing the dynamic loading feature. I think it is worth for three reasons: * it makes initial port easier. * the current common code can't work on ia64 (on ia64 a function pointer is a descriptor and not the address of the first function instruction). * grub-emu doesn't have dynamic modules and could reuse this work to remove most of #ifdef/#endif GRUB_UTIL I have also written a few additionnal EFI specific commands I will post later. Tristan. ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: Grub for ia64
Tristan Gingold wrote: On Thu, Oct 12, 2006 at 05:32:00PM +0200, Johan Rydberg wrote: > Tristan Gingold <[EMAIL PROTECTED]> writes: > > > On Thu, Oct 12, 2006 at 02:11:57PM +0200, Johan Rydberg wrote: > >> Tristan Gingold <[EMAIL PROTECTED]> writes: > >> > >> >> You're telling me that EFI on your IA-64 system does not relocate the > >> >> program before start executing it? That sounds strange. > >> > > >> > It does relocate EFI PEI images. Unfortunatly there is no tools to create > >> > EFI PEI objects on Linux. The gnu efi tools are kludgy: they use standard > >> > gcc and ld, create an ELF image and convert it to a PEI image. But the > >> > relocations are not converted, they are simply put into the data section. > >> > >> How hard would it be to write a converter ourselves, starting with > >> util/i386/efi/grub-mkimage.c? > > Not that hard, but > > * we'd better to have one grub-mkimage.c for all EFI targets > > I agree. > > > * working on binutils is even better. > > The key problem with this as I see it is that it would force people to > have a cross-compiler suite installed, at least for i386 hosts. Unless > we can magically get the default installation to include PE-support. On my debian system, objdump -i: efi-app-ia32 It's already here! The binutils issue is mainly for ia64. For i386, grub-mkimage.c works. Tristan. On i386 objcopy in binutils can convert ELF format into PE32, but application need dynamically relocate itself so that PE32 image can be loaded to any place to execute. For grub-mkimage.c application need not because grub-mkimage will generate dynamic relocate segment. Two methods is ok for me, I prefer the easier one :) thanks bibo,mao ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 1/3] grub efi memory map patch
This patch moves find_mmap_size from i386/efi/linux.c to kern/efi/mm.c, and renamed as grub_efi_find_mmap_size, so that other arch on EFI platform can use this function. Also this function solves memory map too small problem, on some EFI platform MEMORY_MAP_SIZE(0x1000) is a little smaller than EFI memory map table. any suggestion is welcome. thanks bibo,mao diff -Nruap grub2.org/include/grub/efi/api.h grub2/include/grub/efi/api.h --- grub2.org/include/grub/efi/api.h2006-10-24 13:05:48.0 +0800 +++ grub2/include/grub/efi/api.h2006-10-23 14:35:12.0 +0800 @@ -206,6 +206,13 @@ typedef grub_efi_intn_t grub_efi_status_ #define GRUB_EFI_WARN_WRITE_FAILURE GRUB_EFI_WARNING_CODE (3) #define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4) +#define GRUB_EFI_PAGE_SHIFT12 +#define GRUB_EFI_PAGE_SIZE (0x1UL << GRUB_EFI_PAGE_SHIFT) +#define GRUB_EFI_PAGES(addr) (addr >> GRUB_EFI_PAGE_SHIFT) +#define GRUB_EFI_PAGES_UP(addr)((addr + GRUB_EFI_PAGE_SIZE - 1) >> GRUB_EFI_PAGE_SHIFT) +#define PAGE_DOWN(addr)((addr) & (~(GRUB_EFI_PAGE_SIZE - 1))) +#define PAGE_UP(addr) PAGE_DOWN(addr + GRUB_EFI_PAGE_SIZE - 1) + typedef void *grub_efi_handle_t; typedef void *grub_efi_event_t; typedef grub_efi_uint64_t grub_efi_lba_t; diff -Nruap grub2.org/include/grub/efi/efi.h grub2/include/grub/efi/efi.h --- grub2.org/include/grub/efi/efi.h2006-10-24 13:05:48.0 +0800 +++ grub2/include/grub/efi/efi.h2006-10-23 14:42:48.0 +0800 @@ -55,6 +55,7 @@ char *EXPORT_FUNC(grub_efi_get_filename) grub_efi_device_path_t * EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle); int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key); +grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); void grub_efi_mm_init (void); void grub_efi_mm_fini (void); diff -Nruap grub2.org/kern/efi/mm.c grub2/kern/efi/mm.c --- grub2.org/kern/efi/mm.c 2006-10-24 13:05:48.0 +0800 +++ grub2/kern/efi/mm.c 2006-10-24 13:18:48.0 +0800 @@ -30,10 +30,6 @@ #define BYTES_TO_PAGES(bytes) ((bytes) >> 12) #define PAGES_TO_BYTES(pages) ((pages) << 12) -/* The size of a memory map obtained from the firmware. This must be - a multiplier of 4KB. */ -#define MEMORY_MAP_SIZE0x1000 - /* Maintain the list of allocated pages. */ struct allocated_page { @@ -335,6 +331,45 @@ print_memory_map (grub_efi_memory_descri } #endif +/* Find the optimal number of pages for the memory map. */ +grub_efi_uintn_t +grub_efi_find_mmap_size (void) +{ + static grub_efi_uintn_t mmap_size = 0; + + if (mmap_size != 0) +return mmap_size; + + mmap_size = GRUB_EFI_PAGE_SIZE; + while (1) +{ + int ret; + grub_efi_memory_descriptor_t *mmap; + grub_efi_uintn_t desc_size; + + mmap = grub_efi_allocate_pages ( 0, GRUB_EFI_PAGES_UP(mmap_size)); + if (! mmap) +return 0; + + ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); + grub_efi_free_pages ((grub_addr_t) mmap, GRUB_EFI_PAGES_UP(mmap_size)); + + if (ret < 0) +grub_fatal ("cannot get memory map"); + else if (ret > 0) +break; + + mmap_size += GRUB_EFI_PAGE_SIZE; +} + + /* Increase the size a bit for safety, because GRUB allocates more on + later, and EFI itself may allocate more. */ + mmap_size += GRUB_EFI_PAGE_SIZE; + mmap_size = PAGE_UP(mmap_size); + + return mmap_size; +} + void grub_efi_mm_init (void) { @@ -346,6 +381,8 @@ grub_efi_mm_init (void) grub_efi_uintn_t desc_size; grub_efi_uint64_t total_pages; grub_efi_uint64_t required_pages; + grub_efi_uintn_t memory_map_size; + int res; /* First of all, allocate pages to maintain allocations. */ allocated_pages @@ -355,16 +392,20 @@ grub_efi_mm_init (void) grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE); - /* Prepare a memory region to store two memory maps. */ - memory_map = grub_efi_allocate_pages (0, - 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + /* Prepare a memory region to store two memory maps. Obtain size of + memory map by passing a NULL buffer and a buffer size of + zero. */ + memory_map_size = grub_efi_find_mmap_size( ); + memory_map = grub_efi_allocate_pages(0, 2 * PAGE_UP(memory_map_size)); + if (! memory_map) grub_fatal ("cannot allocate memory"); - filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE); + filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, + PAGE_UP(memory_map_size)); /* Obtain descriptors for available memory. */ - map_size = MEMORY_MAP_SIZE; + map_size = memory_map_size; if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0) grub_fatal ("cannot get memory map"); @@ -405,8 +446,7 @@ gr
[patch 2/3] grub efi initrd image memory allocation 4K alignment
Hi, On grub efi platform, initrd image memory allocation start address must be 4K alignment, else it will fail to alloc memory for initrd image. thanks bibo,mao diff -Nruap grub2.org/loader/i386/efi/linux.c grub2/loader/i386/efi/linux.c --- grub2.org/loader/i386/efi/linux.c 2006-10-24 13:24:46.0 +0800 +++ grub2/loader/i386/efi/linux.c 2006-10-24 13:25:35.0 +0800 @@ -587,7 +587,6 @@ grub_rescue_cmd_initrd (int argc, char * desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY - && desc->physical_start >= addr_min && desc->physical_start + size < addr_max && desc->num_pages >= initrd_pages) { @@ -598,7 +597,7 @@ grub_rescue_cmd_initrd (int argc, char * physical_end = addr_max; if (physical_end > addr) - addr = physical_end - page_align (size); + addr = PAGE_DOWN(physical_end - page_align (size)); } } ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 3/3] grub EFI disk device enumberating
Hi, On EFI platform, every partition is regarded as one block device and responding EFI device path. EFI device patch has the same hierarchical relationship with the partition. This patch will search root EFI device path by current device patch, but not parent device path. Original grub can not find efi disk when grub.efi is executed on logical partition. Previously I posted this patch, now I repost again. Any suggestion is welcome. thanks bibo,mao diff -Nruap grub2.org/disk/efi/efidisk.c grub2/disk/efi/efidisk.c --- grub2.org/disk/efi/efidisk.c2006-10-24 13:23:42.0 +0800 +++ grub2/disk/efi/efidisk.c2006-10-24 14:10:32.0 +0800 @@ -87,6 +87,52 @@ find_last_device_path (const grub_efi_de return p; } +static int compare_ancestor_path(const grub_efi_device_path_t *parent, +const grub_efi_device_path_t *dp2) +{ + /* Return non-zero. */ + if (! parent || ! dp2) +return 1; + + while (1) +{ + grub_efi_uint8_t type1, type2; + grub_efi_uint8_t subtype1, subtype2; + grub_efi_uint16_t len1, len2; + int ret; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH(parent)) + break; + + type1 = GRUB_EFI_DEVICE_PATH_TYPE (parent); + type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2); + + if (type1 != type2) + return (int) type2 - (int) type1; + + subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (parent); + subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2); + + if (subtype1 != subtype2) + return (int) subtype1 - (int) subtype2; + + len1 = GRUB_EFI_DEVICE_PATH_LENGTH (parent); + len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2); + + if (len1 != len2) + return (int) len1 - (int) len2; + + ret = grub_memcmp (parent, dp2, len1); + if (ret != 0) + return ret; + + parent = (grub_efi_device_path_t *) ((char *) parent + len1); + dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); +} + + return 0; +} + /* Compare device paths. */ static int compare_device_paths (const grub_efi_device_path_t *dp1, @@ -197,44 +243,6 @@ make_devices (void) return devices; } -/* Find the parent device. */ -static struct grub_efidisk_data * -find_parent_device (struct grub_efidisk_data *devices, - struct grub_efidisk_data *d) -{ - grub_efi_device_path_t *dp, *ldp; - struct grub_efidisk_data *parent; - - dp = duplicate_device_path (d->device_path); - if (! dp) -return 0; - - ldp = find_last_device_path (dp); - ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - ldp->length[0] = sizeof (*ldp); - ldp->length[1] = 0; - - for (parent = devices; parent; parent = parent->next) -{ - /* Ignore itself. */ - if (parent == d) - continue; - - if (compare_device_paths (parent->device_path, dp) == 0) - { - /* Found. */ - if (! parent->last_device_path) - parent = 0; - - break; - } -} - - grub_free (dp); - return parent; -} - static int iterate_child_devices (struct grub_efidisk_data *devices, struct grub_efidisk_data *d, @@ -301,107 +309,36 @@ add_device (struct grub_efidisk_data **d } /* Name the devices. */ -static void -name_devices (struct grub_efidisk_data *devices) -{ +static void name_devices (struct grub_efidisk_data *devices){ struct grub_efidisk_data *d; - - /* First, identify devices by media device paths. */ - for (d = devices; d; d = d->next) -{ - grub_efi_device_path_t *dp; - - dp = d->last_device_path; - if (! dp) - continue; - - if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) - { - int is_hard_drive = 0; - - switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp)) - { - case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: - is_hard_drive = 1; - /* Fall through by intention. */ - case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: - { - struct grub_efidisk_data *parent; - - parent = find_parent_device (devices, d); - if (parent) - { - if (is_hard_drive) - { -#if 0 - grub_printf ("adding a hard drive by a partition: "); - grub_print_device_path (parent->device_path); -#endif - add_device (&hd_devices, parent); - } - else - { -#if 0 - grub_printf ("adding a cdrom by a partition: "); - grub_print_device_path (parent->device_path); -#endif - add_device (&cd_devices, parent); - } - - /* Mark the parent as used. */ - parent->last_device_path = 0; - } - } -
Re: [PATCH 1/3] grub efi memory map patch
hi johan, Thanks for review my patch, I reply in lines. Johan Rydberg wrote: "bibo,mao" <[EMAIL PROTECTED]> writes: > This patch moves find_mmap_size from i386/efi/linux.c to > kern/efi/mm.c, and renamed as grub_efi_find_mmap_size, so that > other arch on EFI platform can use this function. Good call. > Also this function solves memory map too small problem, > on some EFI platform MEMORY_MAP_SIZE(0x1000) is a little smaller > than EFI memory map table. > > any suggestion is welcome. Just a few comments here. I will leave a full review to Okuji. > +#define GRUB_EFI_PAGE_SHIFT 12 > +#define GRUB_EFI_PAGE_SIZE (0x1UL << GRUB_EFI_PAGE_SHIFT) > +#define GRUB_EFI_PAGES(addr) (addr >> GRUB_EFI_PAGE_SHIFT) > +#define GRUB_EFI_PAGES_UP(addr) ((addr + GRUB_EFI_PAGE_SIZE - 1) >> GRUB_EFI_PAGE_SHIFT) > +#define PAGE_DOWN(addr) ((addr) & (~(GRUB_EFI_PAGE_SIZE - 1))) > +#define PAGE_UP(addr)PAGE_DOWN(addr + GRUB_EFI_PAGE_SIZE - 1) The PAGE_DOWN and PAGE_UP macros should be named something else, with a GRUB_EFI prefix. What about GRUB_EFI_PAGE_TRUNC and GRUB_EFI_PAGE_ROUND? Not sure GRUB_EFI_PAGES_UP is needed, since GRUB_EFI_PAGES (GRUB_EFI_PAGE_ROUND (value)) can be used instead. If you find it too long, add a local macro to the file where you use it. It sounds better for me, I rename the macro name as GRUB_EFI_PAGE_TRUNC and GRUB_EFI_PAGE_ROUND, and delete GRUB_EFI_PAGES_UP macro. Also, please slap a few parenthesis round marco arguments. > +/* Find the optimal number of pages for the memory map. */ > +grub_efi_uintn_t > +grub_efi_find_mmap_size (void) > +{ + static grub_efi_uintn_t mmap_size = 0; > ++ if (mmap_size != 0) > +return mmap_size; > ++ mmap_size = GRUB_EFI_PAGE_SIZE; > + while (1) > +{ > + int ret; > + grub_efi_memory_descriptor_t *mmap; > + grub_efi_uintn_t desc_size; > + + mmap = grub_efi_allocate_pages ( 0, > GRUB_EFI_PAGES_UP(mmap_size)); > + if (! mmap) > +return 0; > + + ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, > &desc_size, 0); > + grub_efi_free_pages ((grub_addr_t) mmap, GRUB_EFI_PAGES_UP(mmap_size)); > + + if (ret < 0) > +grub_fatal ("cannot get memory map"); > + else if (ret > 0) > +break; > + + mmap_size += GRUB_EFI_PAGE_SIZE; > +} > + + /* Increase the size a bit for safety, because GRUB allocates > more on > + later, and EFI itself may allocate more. */ > + mmap_size += GRUB_EFI_PAGE_SIZE; > + mmap_size = PAGE_UP(mmap_size); > + + return mmap_size; > +} Is this some patching gone wrong? What are all the "+"'s doing there? The specification states that GetMemoryMap will return EFI_BUFFER_TOO_SMALL and the memory map size in *MemoryMapSize if the memory map could not fit in the buffer (which may be NULL if provided buffer size is too small). Meaning that you can get the size of the memory map by simply doing; grub_efi_uintn_t grub_efi_find_mmap_size (void) { mmap_size = 0; err = grub_efi_get_memory_map (&mmap_size, NULL, 0, NULL, 0); if (err != GRUB_EFI_BUFFER_TOO_SMALL) return err; return mmap_size; } (code not tested, nor compiled.) I think Tristan did this in his patch that addresses the same problem of that the memory map does not fit in a single page. Yes, it is better. But there is one point reserved to notice, grub_efi_find_mmap_size will return current memory map size, if there is memory alloc function, map size will be larger. so allocated (mmap_size + one extra page) buffer for memory map buffer is more reasonable. > + > void > grub_efi_mm_init (void) Whitespace changes are normally not welcome. But they could be removed by the maintainer who commits it. No worries. B> { > @@ -346,6 +381,8 @@ grub_efi_mm_init (void) > grub_efi_uintn_t desc_size; > grub_efi_uint64_t total_pages; > grub_efi_uint64_t required_pages; > + grub_efi_uintn_t memory_map_size; > + int res; > > /* First of all, allocate pages to maintain allocations. */ > allocated_pages > @@ -355,16 +392,20 @@ grub_efi_mm_init (void) > > grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE); > - /* Prepare a memory region to store two memory maps. */ > - memory_map = grub_efi_allocate_pages (0, > - 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); > + /* Prepare a memory region to store two memory maps. Obtain size of > + memory map by passing a NULL buffer and a buffer size of > + zero. */ > + memory_map_size = grub_efi_find_mmap_size( ); > + memory_map = grub_ef
Re: [patch 2/3] grub efi initrd image memory allocation 4K alignment
This patch is sent for second time. thanks bibo,mao diff -Nrup grub2.org/loader/i386/efi/linux.c grub2/loader/i386/efi/linux.c --- grub2.org/loader/i386/efi/linux.c 2006-10-25 12:15:25.0 +0800 +++ grub2/loader/i386/efi/linux.c 2006-10-25 11:40:24.0 +0800 @@ -587,7 +587,6 @@ grub_rescue_cmd_initrd (int argc, char * desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY - && desc->physical_start >= addr_min && desc->physical_start + size < addr_max && desc->num_pages >= initrd_pages) { @@ -598,7 +597,7 @@ grub_rescue_cmd_initrd (int argc, char * physical_end = addr_max; if (physical_end > addr) - addr = physical_end - page_align (size); + addr = GRUB_EFI_PAGE_TRUNC (physical_end - page_align (size)); } } Mao, Bibo wrote: Hi, On grub efi platform, initrd image memory allocation start address must be 4K alignment, else it will fail to alloc memory for initrd image. thanks bibo,mao diff -Nruap grub2.org/loader/i386/efi/linux.c grub2/loader/i386/efi/linux.c --- grub2.org/loader/i386/efi/linux.c 2006-10-24 13:24:46.0 +0800 +++ grub2/loader/i386/efi/linux.c 2006-10-24 13:25:35.0 +0800 @@ -587,7 +587,6 @@ grub_rescue_cmd_initrd (int argc, char * desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY - && desc->physical_start >= addr_min && desc->physical_start + size < addr_max && desc->num_pages >= initrd_pages) { @@ -598,7 +597,7 @@ grub_rescue_cmd_initrd (int argc, char * physical_end = addr_max; if (physical_end > addr) - addr = physical_end - page_align (size); + addr = PAGE_DOWN(physical_end - page_align (size)); } } ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: [PATCH 3/3] grub EFI disk device enumberating
Johan Rydberg wrote: Johan Rydberg <[EMAIL PROTECTED]> writes: > This code can be shorter; you only have to compare the lengths. If > they match, you can do a memcmp on the whole device path. It could look something like this; /* Returns zero if device path SUBPATH is a subpath of device path PATH. */ static int compare_subpath (const grub_efi_device_path_t *subpath, const grub_efi_device_path_t *path) { if (! subpath || ! path) return 1; while (1) { int len, ret; if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (subpath)) return 0; else if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (path)) return 1; if (GRUB_EFI_DEVICE_PATH_LENGTH (subpath) != GRUB_EFI_DEVICE_PATH_LENGTH (path)) return ((int) GRUB_EFI_DEVICE_PATH_LENGTH (subpath) - (int) GRUB_EFI_DEVICE_PATH_LENGTH (path)); len = GRUB_EFI_DEVICE_PATH_LENGTH (path); ret = grub_memcmp (subpath, path, len); if (ret) return ret; path = (grub_efi_device_path_t *) ((char *) path + len); subpath = (grub_efi_device_path_t *) ((char *) subpath + len); } } I guess that should work at least, it is not tested. I tested on my EFI IA32 bios, it works for me, your method is better than me, I incorporated your function in my second patch. thanks bibo,mao In gnufi I have a device_path_iterate function that could be used for these kind of things. Maybe we should bring it in to GRUB2. /* Iterate nodes of the device path. *PATHP should be set to point to the path that is to be iterated. NULL will be returned when the end of the path has been reached. */ efi_device_path_t * efi_device_path_iterate (efi_device_path_t **pathp) { efi_device_path_t *p = *pathp; if (EFI_END_ENTIRE_DEVICE_PATH (p)) return NULL; else { efi_uint_t len = EFI_DEVICE_PATH_LENGTH (p); *pathp = (efi_device_path_t *) (((char *) p) + len); return p; } } ~j --- grub2.org/disk/efi/efidisk.c2006-10-25 12:47:28.0 +0800 +++ grub2/disk/efi/efidisk.c2006-10-25 12:50:19.0 +0800 @@ -87,6 +87,39 @@ find_last_device_path (const grub_efi_de return p; } +/* Returns zero if device path SUBPATH is a subpath of device path + PATH. */ +static int +compare_subpath (const grub_efi_device_path_t *subpath, + const grub_efi_device_path_t *path) +{ + if (! subpath || ! path) +return 1; + + while (1) +{ + int len, ret; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (subpath)) +return 0; + else if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (path)) +return 1; + + if (GRUB_EFI_DEVICE_PATH_LENGTH (subpath) + != GRUB_EFI_DEVICE_PATH_LENGTH (path)) +return ((int) GRUB_EFI_DEVICE_PATH_LENGTH (subpath) +- (int) GRUB_EFI_DEVICE_PATH_LENGTH (path)); + + len = GRUB_EFI_DEVICE_PATH_LENGTH (path); + ret = grub_memcmp (subpath, path, len); + if (ret) +return ret; + + path = (grub_efi_device_path_t *) ((char *) path + len); + subpath = (grub_efi_device_path_t *) ((char *) subpath + len); +} +} + /* Compare device paths. */ static int compare_device_paths (const grub_efi_device_path_t *dp1, @@ -197,44 +230,6 @@ make_devices (void) return devices; } -/* Find the parent device. */ -static struct grub_efidisk_data * -find_parent_device (struct grub_efidisk_data *devices, - struct grub_efidisk_data *d) -{ - grub_efi_device_path_t *dp, *ldp; - struct grub_efidisk_data *parent; - - dp = duplicate_device_path (d->device_path); - if (! dp) -return 0; - - ldp = find_last_device_path (dp); - ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - ldp->length[0] = sizeof (*ldp); - ldp->length[1] = 0; - - for (parent = devices; parent; parent = parent->next) -{ - /* Ignore itself. */ - if (parent == d) - continue; - - if (compare_device_paths (parent->device_path, dp) == 0) - { - /* Found. */ - if (! parent->last_device_path) - parent = 0; - - break; - } -} - - grub_free (dp); - return parent; -} - static int iterate_child_devices (struct grub_efidisk_data *devices, struct grub_efidisk_data *d, @@ -305,63 +300,6 @@ static void name_devices (struct grub_efidisk_data *devices) { struct grub_efidisk_data *d; - - /* First, identify devices by media device paths. */ - for (d = devices; d; d = d->next) -{ - grub_efi_device_path_t *dp; - - dp = d->last_device_path; - if (! dp) - continue; - - if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) - { - int is_hard_drive = 0; - - switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp)) - { - case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: -
Re: multiboot2: variable data size
Yoshinori K. Okuji wrote: On Tuesday 28 November 2006 10:29, Johan Rydberg wrote: > "Yoshinori K. Okuji" <[EMAIL PROTECTED]> writes: > > On Saturday 25 November 2006 04:33, Hollis Blanchard wrote: > >> That's exactly the point: there will be no difference. Both > >> architectures will use 64-bit types. > > > > No. Both should use 32-bit, because GRUB transfers control in 32-bit > > mode. Passing 64-bit addresses would be useless in this case. Note that > > the memory map information is 64-bit even in the previous version of > > Multiboot Spec. > > That will not be true for x86_64-efi, which will have to run in long > mode. Oh, sorry. I meant "x86_64-pc" in the previous message. I just omitted "pc". When the firmware is different, it is feasible to make a different spec, but... But is it true that EFI starts with 64-bit mode? Where is it defined? In UEFI? Could you give me a pointer? yes, x84_64EFI starts with 64-bit long mode and page enabled(virtual address equals physical address) if it is x86_64 efi bios, it is defined in section 2.3.4 of UEFI Specification Version 2.0. If kernel image is bzImage, x64 efi bootloader need switch to 32 bit protect mode(or real mode) from 64 bit long mode, and if kernel image is gzipped/plain format, efi bootloader can directly jump to 64-bit kernel entry address without mode switch. thanks bibo,mao ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: multiboot2: variable data size
Yoshinori K. Okuji wrote: On Tuesday 28 November 2006 13:46, bibo,mao wrote: > yes, x84_64EFI starts with 64-bit long mode and page enabled(virtual > address equals physical address) if it is x86_64 efi bios, it is defined in > section 2.3.4 of UEFI Specification Version 2.0. > > If kernel image is bzImage, x64 efi bootloader need switch to 32 bit > protect mode(or real mode) from 64 bit long mode, and if kernel image is > gzipped/plain format, efi bootloader can directly jump to 64-bit kernel > entry address without mode switch. Thanks for your detailed information. So does it mean that GRUB needs to provide a PE32+ application to EFI, if it is on x86_64? Or does it understand PE32? More information is welcome. Now I tried on x86_64, it seems that x86_64 efi bios does not support PE32 format, PE32+ application should be provided. BTW, in the current implementation, GRUB skips real mode setup code in Linux and directly jumps to a protected mode entry on EFI. Can we use the same trick with bzImage on x86_64? Mode switching is not difficult, but if we can omit it, that would be much easier to implement. On i386 efi platform, real mode setup code can be skipped with bzImage. But on x86_64 efi platform with bzImage format, it seems that it need switch to 32-bit protect mode at least. We can discard mode switching at beginning so that it can boot kernel image with gzipped format. Mode switching code is not difficult and very small, the problem is that x86_64 bootloader(pe32+) can be loaded at address beyond 4G, but mode switching code must be within 4G, also self-uncompressed bzimage code possibly flushes mode switching code. I do not know which address is safe to put switching code, how about 0x7c00? thanks bibo,mao Okuji ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: multiboot2: variable data size
Johan Rydberg wrote: "bibo,mao" <[EMAIL PROTECTED]> writes: > If kernel image is bzImage, x64 efi bootloader need switch to 32 bit > protect mode(or real mode) from 64 bit long mode, and if kernel > image is gzipped/plain format, efi bootloader can directly jump to > 64-bit kernel entry address without mode switch. My opinion is that bzImages should be avoided on EFI platforms, or the decompress-code in Linux has to be rewritten. bzImage supporting mainly is to be compliant with legacy bios, user need not care for detailed bootloader procedure, user always installs linux kernel with command "make install" which will generate bzImage format. Now on some platform there are two kinds of bios: efi bios and legacy bios, if bzImage is supported then one kernel image can run two kinds of bios. It took me a good couple of hours of debugging to find out that Linux simply ignores the memory layout and assumes that low memory is free to use as it likes. current decompress-code with bzImage possibly touches low memory at 0x1000--0x9000, or decompress-code needs to be rewritten, or put mode switching code below 0x1000. thanks bibo,mao ~j ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
grub EFI signature should be little endian
hi, EFI bootloader signature is "EFIL" string, x86 machine is little-endian. This patch changes grub efi booloader sigature as little-endian. thanks bibo,mao --- grub2.org/include/grub/i386/linux.h 2006-12-06 17:51:19.0 +0800 +++ grub2/include/grub/i386/linux.h 2006-12-06 17:52:50.0 +0800 @@ -46,7 +46,7 @@ #define GRUB_LINUX_CL_MAGIC 0xA33F #define GRUB_LINUX_EFI_SIGNATURE\ - ('E' << 24 | 'F' << 16 | 'I' << 8 | 'L') + ('L' << 24 | 'I' << 16 | 'F' << 8 | 'E') #ifndef ASM_FILE ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: EFI-dualbooting OSX and Linux on iMac with T7400-CPU
Eeri Kask wrote: Yoshinori K. Okuji wrote: >> (line 2-2) >> syntax error >> Incorrect command >> ... >> (line 12-12) >> Press any key to continue... > > Hmm.. I think you need to put the open braces in the same line as "menuentry" > commands. Thank you for the hint! :-) So now my grub.cfg looks menuentry "MacOSX" { set root=(hd0,2) chainloader /System/Library/CoreServices/boot.efi } menuentry "GNU/Linux" { set root=(hd0,5) linux /boot/vmlinuz root=/dev/sda5 } and grub shows text-mode menu similar to the old version "0.97". I think grub is working perfectly well since I can boot MacOSX as one would expect it to do (my supposition about eventually not reading HFS+ journaled filesystems luckily proved to be false). Then, selecting 'GNU/Linux' shows Booting 'GNU/Linux' [Linux-EFI, setup=0x1e00, size=0x231796] There is no initrd option in your menu, I do not know whether it can successfully boot up without initrd option with grub2. you can enter into rescue mode(command-line mode), and enter commands like this: $linux /boot/vmlinuz root=/dev/sda5 $initrd /boot/xxx $boot And what is your linux kernel version? and from now on nothing appears to the screen. Shortly thereafter I notice USB-keyboard LEDs blinking on-off (num-lock, caps-lock, scroll-lock) at some time point, so maybe Linux is in the middle of booting I simply cannot visually observe. Assuming booting is in progress, at some stage it fails though; otherwise I should have remote ssh-access if it had finished properly, staying in some unusable video state. So as you described, graphics drivers need to be investigated and patched. > BTW, this report seems to be a proof that x86_64 starts up in 32-bit mode even > on EFI, well, in Intel Mac. So do we really need to implement 64-bit support > for x86_64? As said, I was able to boot MacOSX 10.4.8 without any trouble on iMac intel T7400-cpu only using current grub2 from cvs (i.e. without bootcamp, without refit, etc. etc.). Though, after finishing installation, without asking me MacOSX over the network automatically updated firmware, hopefully to the current latest version. Greetings, Eeri Kask ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: EFI-dualbooting OSX and Linux on iMac with T7400-CPU
Eeri Kask wrote: bibo,mao wrote: >> menuentry "MacOSX" { >> set root=(hd0,2) >> chainloader /System/Library/CoreServices/boot.efi >> } >> >> menuentry "GNU/Linux" { >> set root=(hd0,5) >> linux /boot/vmlinuz root=/dev/sda5 >> } >> > There is no initrd option in your menu, I do not know whether it can > successfully boot up without initrd option with grub2. you can enter > into rescue mode(command-line mode), and enter commands like this: > $linux /boot/vmlinuz root=/dev/sda5 > $initrd /boot/xxx > $boot > > And what is your linux kernel version? 2.6.18.5. There exists one bug in Linux kernel only EFI bios relative at http://marc.theaimsgroup.com/?l=linux-kernel&m=116157536316034&w=2 I do not know whether 2.6.18.5 incorporates this bug. initrd is in my case in fact not needed; I compiled ata_piix and ext3 drivers, and everything inbetween directly into the kernel, so if correctly loaded, it should be able to access /dev/sda5 and retrieve /sbin/init from the hard disk; then everything else comes from there as well. Currently I am a little puzzled, as grub2 loads and executes MacOS-X boot.efi correctly, but if trying linux, then linux stops somewhere. As next, if burning the same kernel image as a bootable syslinux-CD, linux gets loaded and executed as one would expect. With the "nv" driver even X11 runs in full 1920x1200 resolution on iMac-T7400 excellently (nvidia proprietary driver builds, starts and runs without complaints, but shows "black pixels" only :-). Maybe MacOS if booting from CD sets up some faked BIOS environment so Linux and X11 are in believing it is usual IBM-PC-hardware, but if booting with grub2 this is not the case and then linux fails? I am not familiar with Mac machine, In general there exists two types of bios. One is EFI bios, the other is legacy pc bios. I doubt that syslinux-CD boots from legacy pc bios but not EFI bios. You can enter "dmesg" command to find memory map information to judge which bios kernel boots from. thanks bibo, mao Momentarily I am not convinced it is a grub2 issue. Greetings, Eeri Kask ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel
Re: EFI-dualbooting OSX and Linux on iMac with T7400-CPU
Eeri Kask wrote: bibo,mao wrote: >> 2.6.18.5. > There exists one bug in Linux kernel only EFI bios relative at > http://marc.theaimsgroup.com/?l=linux-kernel&m=116157536316034&w=2 <http://marc.theaimsgroup.com/?l=linux-kernel&m=116157536316034&w=2> > I do not know whether 2.6.18.5 incorporates this bug. Oh, I see. This bug is not corrected in 2.6.18.5. As a side note, in contrast, in "arch/x86_64/kernel/" there are seemingly no files having anything to do with efi. Maybe this is of no importance though. x86_64 currently does not support EFI bios, there is no x86_64 efi booloader and x86_64 kernel does not support EFI bios now. Soon x86_64 kernel patch and grub bootloader patch will be published out. From your dmesg information, system boots from legacy bios. When machine is powered on, EFI bios is loaded first and then lagacy bios is loaded if there is no response. >> Maybe MacOS if booting from CD sets up some faked BIOS environment so >> Linux and X11 are in believing it is usual IBM-PC-hardware, but if >> booting with grub2 this is not the case and then linux fails? > I am not familiar with Mac machine, In general there exists two types of > bios. One is EFI bios, the other is legacy pc bios. I doubt that > syslinux-CD boots from legacy pc bios but not EFI bios. You can enter > "dmesg" command to find memory map information to judge which bios kernel > boots from. :-) I sincerely apologise for the long attachment in advance; here I send you the dmesg output in full, most of it I do not understand. Greetings, Eeri Kask 8<8< Bootdata ok (command line is root=/dev/sda5 BOOT_IMAGE=bzImage ) Linux version 2.6.18.5 ([EMAIL PROTECTED]) (gcc version 4.1.1 (Gentoo 4.1.1)) #1 SMP PREEMPT Wed Dec 6 16:09:02 CET 2006 BIOS-provided physical RAM map: BIOS-e820: - 0009fc00 (usable) BIOS-e820: 0009fc00 - 000a (reserved) BIOS-e820: 000e - 0010 (reserved) BIOS-e820: 0010 - 7f103000 (usable) BIOS-e820: 7f103000 - 7f304000 (ACPI NVS) BIOS-e820: 7f304000 - 7febe000 (ACPI data) BIOS-e820: 7febe000 - 7feef000 (ACPI NVS) BIOS-e820: 7feef000 - 7ff0 (ACPI data) BIOS-e820: 7ff0 - 8000 (reserved) BIOS-e820: f000 - f400 (reserved) BIOS-e820: fec0 - fec01000 (reserved) BIOS-e820: fed14000 - fed1a000 (reserved) BIOS-e820: fed1c000 - fed2 (reserved) BIOS-e820: fee0 - fee01000 (reserved) BIOS-e820: ffe0 - 0001 (reserved) the memory map information shows that it is e820 map information, it is legacy bios memory map information. Currently Linux only supports EFI bios on IA32 platform. thanks bibo,mao ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel ___ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel