diff --git a/ChangeLog b/ChangeLog index 1de68ad..6171d02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2009-08-25 Vladimir Serbinenko + NetBSD memory map support. + + * include/grub/i386/bsd.h (NETBSD_BTINFO_MEMMAP): New definition. + (grub_netbsd_btinfo_mmap_header): New structure. + (grub_netbsd_btinfo_mmap_entry): Likewise. + * loader/i386/bsd.c (grub_netbsd_boot): Pass memory map. + +2009-08-25 Vladimir Serbinenko + Cleanup NetBSD root support. * loader/i386/bsd.c (grub_netbsd_boot): Remove call to diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index 2939035..8ffaf7d 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -203,6 +203,7 @@ struct grub_netbsd_bootinfo #define NETBSD_BTINFO_BOOTPATH 0 #define NETBSD_BTINFO_ROOTDEVICE 1 #define NETBSD_BTINFO_BOOTDISK 3 +#define NETBSD_BTINFO_MEMMAP 9 struct grub_netbsd_btinfo_common { @@ -210,6 +211,23 @@ struct grub_netbsd_btinfo_common int type; }; +struct grub_netbsd_btinfo_mmap_header +{ + struct grub_netbsd_btinfo_common common; + grub_uint32_t count; +}; + +struct grub_netbsd_btinfo_mmap_entry +{ + grub_uint64_t addr; + grub_uint64_t len; +#define NETBSD_MMAP_AVAILABLE 1 +#define NETBSD_MMAP_RESERVED 2 +#define NETBSD_MMAP_ACPI 3 +#define NETBSD_MMAP_NVS 4 + grub_uint32_t type; +}; + struct grub_netbsd_btinfo_bootpath { struct grub_netbsd_btinfo_common common; diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 0b9a2b4..6b532f2 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -626,30 +626,87 @@ static grub_err_t grub_netbsd_boot (void) { struct grub_netbsd_bootinfo *bootinfo; + int count = 0; + struct grub_netbsd_btinfo_mmap_header *mmap; + struct grub_netbsd_btinfo_mmap_entry *pm; + void *curarg; + + auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_uint32_t type __attribute__ ((unused))) + { + count++; + return 0; + } + + auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + pm->addr = addr; + pm->len = size; + + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + pm->type = NETBSD_MMAP_AVAILABLE; + break; + + case GRUB_MACHINE_MEMORY_ACPI: + pm->type = NETBSD_MMAP_ACPI; + break; + + case GRUB_MACHINE_MEMORY_NVS: + pm->type = NETBSD_MMAP_NVS; + break; + + default: + pm->type = NETBSD_MMAP_RESERVED; + break; + } + pm++; + + return 0; + } + + grub_mmap_iterate (count_hook); if (kern_end + sizeof (struct grub_netbsd_btinfo_rootdevice) - + sizeof (struct grub_netbsd_bootinfo) > grub_os_area_addr - + grub_os_area_size) + + sizeof (struct grub_netbsd_bootinfo) + + sizeof (struct grub_netbsd_btinfo_mmap_header) + + count * sizeof (struct grub_netbsd_btinfo_mmap_entry) + > grub_os_area_addr + grub_os_area_size) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "No memory for boot info."); + curarg = mmap = (struct grub_netbsd_btinfo_mmap_header *) kern_end; + pm = (struct grub_netbsd_btinfo_mmap_entry *) (mmap + 1); + + grub_mmap_iterate (fill_hook); + mmap->common.type = NETBSD_BTINFO_MEMMAP; + mmap->common.len = (char *) pm - (char *) mmap; + mmap->count = count; + curarg = pm; + if (netbsd_root) { struct grub_netbsd_btinfo_rootdevice *rootdev; - rootdev = (struct grub_netbsd_btinfo_rootdevice *) kern_end; + rootdev = (struct grub_netbsd_btinfo_rootdevice *) curarg; rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice); rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE; grub_strncpy (rootdev->devname, netbsd_root, sizeof (rootdev->devname)); bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1); - bootinfo->bi_count = 1; - bootinfo->bi_data[0] = rootdev; + bootinfo->bi_count = 2; + bootinfo->bi_data[0] = mmap; + bootinfo->bi_data[1] = rootdev; } else { - bootinfo = (struct grub_netbsd_bootinfo *) kern_end; - bootinfo->bi_count = 0; + bootinfo = (struct grub_netbsd_bootinfo *) curarg; + bootinfo->bi_count = 1; + bootinfo->bi_data[0] = mmap; } grub_unix_real_boot (entry, bootflags, 0, bootinfo,