15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* boot.c - load and bootstrap a kernel */ 25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * GRUB -- GRand Unified Bootloader 45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. 55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This program is free software; you can redistribute it and/or modify 75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * it under the terms of the GNU General Public License as published by 85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the Free Software Foundation; either version 2 of the License, or 95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * (at your option) any later version. 105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This program is distributed in the hope that it will be useful, 125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * GNU General Public License for more details. 155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * You should have received a copy of the GNU General Public License 175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * along with this program; if not, write to the Free Software 185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "shared.h" 235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "freebsd.h" 255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "imgact_aout.h" 265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "i386-elf.h" 275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int cur_addr; 295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectentry_func entry_addr; 305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct mod_list mll[99]; 315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int linux_mem_size; 325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * The next two functions, 'load_image' and 'load_module', are the building 355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * blocks of the multiboot loader component. They handle essentially all 365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * of the gory details of loading in a bootable image and the modules. 375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectkernel_t 405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectload_image (char *kernel, char *arg, kernel_t suggested_type, 415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned long load_flags) 425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int len, i, exec_type = 0, align_4k = 1; 445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_func real_entry_addr = 0; 455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project kernel_t type = KERNEL_TYPE_NONE; 465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0; 475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *str = 0, *str2 = 0; 485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct linux_kernel_header *lh; 495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project union 505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct multiboot_header *mb; 525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct exec *aout; 535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Elf32_Ehdr *elf; 545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pu; 565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* presuming that MULTIBOOT_SEARCH is large enough to encompass an 575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project executable header */ 585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char buffer[MULTIBOOT_SEARCH]; 595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* sets the header pointer to point to the beginning of the 615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project buffer by default */ 625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pu.aout = (struct exec *) buffer; 635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!grub_open (kernel)) 655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return KERNEL_TYPE_NONE; 665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32) 685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!errnum) 725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return KERNEL_TYPE_NONE; 755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < len; i++) 785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (MULTIBOOT_FOUND ((int) (buffer + i), len - i)) 805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project flags = ((struct multiboot_header *) (buffer + i))->flags; 825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (flags & MULTIBOOT_UNSUPPORTED) 835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_BOOT_FEATURES; 865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return KERNEL_TYPE_NONE; 875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project type = KERNEL_TYPE_MULTIBOOT; 895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str2 = "Multiboot"; 905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Use BUFFER as a linux kernel header, if the image is Linux zImage 955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project or bzImage. */ 965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh = (struct linux_kernel_header *) buffer; 975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* ELF loading supported if multiboot, FreeBSD and NetBSD. */ 995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((type == KERNEL_TYPE_MULTIBOOT 1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD 1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0 1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || suggested_type == KERNEL_TYPE_NETBSD) 1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && len > sizeof (Elf32_Ehdr) 1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer)))) 1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (type == KERNEL_TYPE_MULTIBOOT) 1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_addr = (entry_func) pu.elf->e_entry; 1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF); 1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (entry_addr < (entry_func) 0x100000) 1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_BELOW_1MB; 1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* don't want to deal with ELF program header at some random 1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project place in the file -- this generally won't happen */ 1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (pu.elf->e_phoff == 0 || pu.elf->e_phnum == 0 1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || ((pu.elf->e_phoff + (pu.elf->e_phentsize * pu.elf->e_phnum)) 1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project >= len)) 1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str = "elf"; 1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (type == KERNEL_TYPE_NONE) 1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* At the moment, there is no way to identify a NetBSD ELF 1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project kernel, so rely on the suggested type by the user. */ 1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (suggested_type == KERNEL_TYPE_NETBSD) 1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str2 = "NetBSD"; 1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project type = suggested_type; 1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str2 = "FreeBSD"; 1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project type = KERNEL_TYPE_FREEBSD; 1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (flags & MULTIBOOT_AOUT_KLUDGE) 1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pu.mb = (struct multiboot_header *) (buffer + i); 1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_addr = (entry_func) pu.mb->entry_addr; 1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = pu.mb->load_addr; 1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* first offset into file */ 1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_seek (i - (pu.mb->header_addr - cur_addr)); 1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* If the load end address is zero, load the whole contents. */ 1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! pu.mb->load_end_addr) 1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pu.mb->load_end_addr = cur_addr + filemax; 1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project text_len = pu.mb->load_end_addr - cur_addr; 1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project data_len = 0; 1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* If the bss end address is zero, assume that there is no bss area. */ 1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! pu.mb->bss_end_addr) 1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pu.mb->bss_end_addr = pu.mb->load_end_addr; 1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bss_len = pu.mb->bss_end_addr - pu.mb->load_end_addr; 1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (pu.mb->header_addr < pu.mb->load_addr 1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || pu.mb->load_end_addr <= pu.mb->load_addr 1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || pu.mb->bss_end_addr < pu.mb->load_end_addr 1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || (pu.mb->header_addr - pu.mb->load_addr) > i) 1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (cur_addr < 0x100000) 1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_BELOW_1MB; 1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pu.aout = (struct exec *) buffer; 1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project exec_type = 2; 1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str = "kludge"; 1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (len > sizeof (struct exec) && !N_BADMAG ((*(pu.aout)))) 1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_addr = (entry_func) pu.aout->a_entry; 1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (type == KERNEL_TYPE_NONE) 1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * If it doesn't have a Multiboot header, then presume 1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * it is either a FreeBSD or NetBSD executable. If so, 1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * then use a magic number of normal ordering, ZMAGIC to 1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * determine if it is FreeBSD. 1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This is all because freebsd and netbsd seem to require 1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * masking out some address bits... differently for each 1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * one... plus of course we need to know which booting 1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * method to use. 1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_addr = (entry_func) ((int) entry_addr & 0xFFFFFF); 1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (buffer[0] == 0xb && buffer[1] == 1) 1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project type = KERNEL_TYPE_FREEBSD; 1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = (int) entry_addr; 1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str2 = "FreeBSD"; 1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project type = KERNEL_TYPE_NETBSD; 2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = (int) entry_addr & 0xF00000; 2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (N_GETMAGIC ((*(pu.aout))) != NMAGIC) 2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project align_4k = 0; 2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str2 = "NetBSD"; 2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* first offset into file */ 2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_seek (N_TXTOFF (*(pu.aout))); 2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project text_len = pu.aout->a_text; 2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project data_len = pu.aout->a_data; 2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bss_len = pu.aout->a_bss; 2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (cur_addr < 0x100000) 2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_BELOW_1MB; 2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project exec_type = 1; 2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str = "a.out"; 2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (lh->boot_flag == BOOTSEC_SIGNATURE 2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && lh->setup_sects <= LINUX_MAX_SETUP_SECTS) 2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int big_linux = 0; 2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int setup_sects = lh->setup_sects; 2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0200) 2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project big_linux = (lh->loadflags & LINUX_FLAG_BIG_KERNEL); 2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->type_of_loader = LINUX_BOOT_LOADER_TYPE; 2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Put the real mode part at as a high location as possible. */ 2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_data_real_addr 2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project = (char *) ((mbi.mem_lower << 10) - LINUX_SETUP_MOVE_SIZE); 2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* But it must not exceed the traditional area. */ 2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (linux_data_real_addr > (char *) LINUX_OLD_REAL_MODE_ADDR) 2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR; 2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (lh->version >= 0x0201) 2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->heap_end_ptr = LINUX_HEAP_END_OFFSET; 2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->loadflags |= LINUX_FLAG_CAN_USE_HEAP; 2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (lh->version >= 0x0202) 2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_OFFSET; 2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->cl_magic = LINUX_CL_MAGIC; 2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->cl_offset = LINUX_CL_OFFSET; 2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->setup_move_size = LINUX_SETUP_MOVE_SIZE; 2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Your kernel is quite old... */ 2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->cl_magic = LINUX_CL_MAGIC; 2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->cl_offset = LINUX_CL_OFFSET; 2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project setup_sects = LINUX_DEFAULT_SETUP_SECTS; 2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR; 2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* If SETUP_SECTS is not set, set it to the default (4). */ 2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! setup_sects) 2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project setup_sects = LINUX_DEFAULT_SETUP_SECTS; 2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project data_len = setup_sects << 9; 2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project text_len = filemax - data_len - SECTOR_SIZE; 2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_data_tmp_addr = (char *) LINUX_BZIMAGE_ADDR + text_len; 2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! big_linux 2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && text_len > linux_data_real_addr - (char *) LINUX_ZIMAGE_ADDR) 2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_printf (" linux 'zImage' kernel too big, try 'make bzImage'\n"); 2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_WONT_FIT; 2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (linux_data_real_addr + LINUX_SETUP_MOVE_SIZE 2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project > RAW_ADDR ((char *) (mbi.mem_lower << 10))) 2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_WONT_FIT; 2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", 2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (big_linux ? "bzImage" : "zImage"), data_len, text_len); 2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Video mode selection support. What a mess! */ 2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* NOTE: Even the word "mess" is not still enough to 2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project represent how wrong and bad the Linux video support is, 2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project but I don't want to hear complaints from Linux fanatics 2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project any more. -okuji */ 2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *vga; 2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Find the substring "vga=". */ 2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project vga = grub_strstr (arg, "vga="); 2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (vga) 2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *value = vga + 4; 2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int vid_mode; 3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Handle special strings. */ 3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (substring ("normal", value) < 1) 3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project vid_mode = LINUX_VID_MODE_NORMAL; 3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (substring ("ext", value) < 1) 3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project vid_mode = LINUX_VID_MODE_EXTENDED; 3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (substring ("ask", value) < 1) 3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project vid_mode = LINUX_VID_MODE_ASK; 3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (safe_parse_maxint (&value, &vid_mode)) 3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ; 3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* ERRNUM is already set inside the function 3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project safe_parse_maxint. */ 3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return KERNEL_TYPE_NONE; 3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->vid_mode = vid_mode; 3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Check the mem= option to limit memory used for initrd. */ 3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *mem; 3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mem = grub_strstr (arg, "mem="); 3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (mem) 3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *value = mem + 4; 3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project safe_parse_maxint (&value, &linux_mem_size); 3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project switch (errnum) 3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case ERR_NUMBER_OVERFLOW: 3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* If an overflow occurs, use the maximum address for 3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project initrd instead. This is good, because MAXINT is 3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project greater than LINUX_INITRD_MAX_ADDRESS. */ 3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_mem_size = LINUX_INITRD_MAX_ADDRESS; 3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_NONE; 3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case ERR_NONE: 3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int shift = 0; 3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project switch (grub_tolower (*value)) 3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case 'g': 3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project shift += 10; 3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case 'm': 3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project shift += 10; 3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case 'k': 3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project shift += 10; 3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project default: 3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Check an overflow. */ 3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (linux_mem_size > (MAXINT >> shift)) 3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_mem_size = LINUX_INITRD_MAX_ADDRESS; 3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_mem_size <<= shift; 3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project default: 3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_mem_size = 0; 3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_NONE; 3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_mem_size = 0; 3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* It is possible that DATA_LEN + SECTOR_SIZE is greater than 3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project MULTIBOOT_SEARCH, so the data may have been read partially. */ 3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (data_len + SECTOR_SIZE <= MULTIBOOT_SEARCH) 3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_memmove (linux_data_tmp_addr, buffer, 3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project data_len + SECTOR_SIZE); 3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_memmove (linux_data_tmp_addr, buffer, MULTIBOOT_SEARCH); 3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_read (linux_data_tmp_addr + MULTIBOOT_SEARCH, 3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project data_len + SECTOR_SIZE - MULTIBOOT_SEARCH); 3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (lh->header != LINUX_MAGIC_SIGNATURE || 3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->version < 0x0200) 3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Clear the heap space. */ 3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_memset (linux_data_tmp_addr + ((setup_sects + 1) << 9), 3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 0, 3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (64 - setup_sects - 1) << 9); 3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Copy command-line plus memory hack to staging area. 3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project NOTE: Linux has a bug that it doesn't handle multiple spaces 3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project between two options and a space after a "mem=" option isn't 3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project removed correctly so the arguments to init could be like 3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"init", "", "", NULL}. This affects some not-very-clever 4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project shells. Thus, the code below does a trick to avoid the bug. 4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project That is, copy "mem=XXX" to the end of the command-line, and 4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project avoid to copy spaces unnecessarily. Hell. */ 4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *src = skip_to (0, arg); 4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *dest = linux_data_tmp_addr + LINUX_CL_OFFSET; 4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (dest < linux_data_tmp_addr + LINUX_CL_END_OFFSET && *src) 4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *(dest++) = *(src++); 4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Old Linux kernels have problems determining the amount of 4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project the available memory. To work around this problem, we add 4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project the "mem" option to the kernel command line. This has its 4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project own drawbacks because newer kernels can determine the 4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memory map more accurately. Boot protocol 2.03, which 4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project appeared in Linux 2.4.18, provides a pointer to the kernel 4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project version string, so we could check it. But since kernel 4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2.4.18 and newer are known to detect memory reliably, boot 4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project protocol 2.03 already implies that the kernel is new 4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project enough. The "mem" option is added if neither of the 4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project following conditions is met: 4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1) The "mem" option is already present. 4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2) The "kernel" command is used with "--no-mem-option". 4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3) GNU GRUB is configured not to pass the "mem" option. 4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4) The kernel supports boot protocol 2.03 or newer. */ 4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! grub_strstr (arg, "mem=") 4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && ! (load_flags & KERNEL_LOAD_NO_MEM_OPTION) 4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && lh->version < 0x0203 /* kernel version < 2.4.18 */ 4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && dest + 15 < linux_data_tmp_addr + LINUX_CL_END_OFFSET) 4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *dest++ = ' '; 4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *dest++ = 'm'; 4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *dest++ = 'e'; 4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *dest++ = 'm'; 4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *dest++ = '='; 4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400)); 4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *dest++ = 'K'; 4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *dest = 0; 4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* offset into file */ 4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_seek (data_len + SECTOR_SIZE); 4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = (int) linux_data_tmp_addr + LINUX_SETUP_MOVE_SIZE; 4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_read ((char *) LINUX_BZIMAGE_ADDR, text_len); 4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (errnum == ERR_NONE) 4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Sanity check. */ 4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (suggested_type != KERNEL_TYPE_NONE 4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && ((big_linux && suggested_type != KERNEL_TYPE_BIG_LINUX) 4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || (! big_linux && suggested_type != KERNEL_TYPE_LINUX))) 4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return KERNEL_TYPE_NONE; 4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Ugly hack. */ 4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project linux_text_len = text_len; 4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return big_linux ? KERNEL_TYPE_BIG_LINUX : KERNEL_TYPE_LINUX; 4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else /* no recognizable format */ 4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* return if error */ 4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (errnum) 4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return KERNEL_TYPE_NONE; 4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* fill the multiboot info structure */ 4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.cmdline = (int) arg; 4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.mods_count = 0; 4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.mods_addr = 0; 4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.boot_device = (current_drive << 24) | current_partition; 4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.flags &= ~(MB_INFO_MODS | MB_INFO_AOUT_SYMS | MB_INFO_ELF_SHDR); 4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.tabsize = 0; 4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.strsize = 0; 4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.addr = 0; 4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.pad = 0; 4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (" [%s-%s", str2, str); 4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str = ""; 4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (exec_type) /* can be loaded like a.out */ 4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (flags & MULTIBOOT_AOUT_KLUDGE) 4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str = "-and-data"; 4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", loadaddr=0x%x, text%s=0x%x", cur_addr, str, text_len); 5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* read text, then read data */ 5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (grub_read ((char *) RAW_ADDR (cur_addr), text_len) == text_len) 5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += text_len; 5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!(flags & MULTIBOOT_AOUT_KLUDGE)) 5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* we have to align to a 4K boundary */ 5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (align_4k) 5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; 5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", C"); 5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", data=0x%x", data_len); 5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((grub_read ((char *) RAW_ADDR (cur_addr), data_len) 5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project != data_len) 5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && !errnum) 5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += data_len; 5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!errnum) 5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memset ((char *) RAW_ADDR (cur_addr), 0, bss_len); 5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += bss_len; 5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", bss=0x%x", bss_len); 5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (!errnum) 5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!errnum && pu.aout->a_syms 5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && pu.aout->a_syms < (filemax - filepos)) 5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int symtab_err, orig_addr = cur_addr; 5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* we should align to a 4K boundary here for good measure */ 5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (align_4k) 5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; 5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.addr = cur_addr; 5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((int *) RAW_ADDR (cur_addr)) = pu.aout->a_syms; 5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += sizeof (int); 5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", symtab=0x%x", pu.aout->a_syms); 5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (grub_read ((char *) RAW_ADDR (cur_addr), pu.aout->a_syms) 5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project == pu.aout->a_syms) 5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += pu.aout->a_syms; 5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.tabsize = pu.aout->a_syms; 5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (grub_read ((char *) &i, sizeof (int)) == sizeof (int)) 5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((int *) RAW_ADDR (cur_addr)) = i; 5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += sizeof (int); 5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.strsize = i; 5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project i -= sizeof (int); 5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", strtab=0x%x", i); 5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project symtab_err = (grub_read ((char *) RAW_ADDR (cur_addr), i) 5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project != i); 5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += i; 5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project symtab_err = 1; 5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project symtab_err = 1; 5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (symtab_err) 5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf ("(bad)"); 5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = orig_addr; 5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.tabsize = 0; 5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.strsize = 0; 5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.a.addr = 0; 5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.flags |= MB_INFO_AOUT_SYMS; 5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* ELF executable */ 5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned loaded = 0, memaddr, memsiz, filesiz; 5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Elf32_Phdr *phdr; 5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* reset this to zero for now */ 5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = 0; 5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* scan for program segments */ 5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < pu.elf->e_phnum; i++) 6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phdr = (Elf32_Phdr *) 6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (pu.elf->e_phoff + ((int) buffer) 6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project + (pu.elf->e_phentsize * i)); 6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (phdr->p_type == PT_LOAD) 6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* offset into file */ 6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_seek (phdr->p_offset); 6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project filesiz = phdr->p_filesz; 6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (type == KERNEL_TYPE_FREEBSD || type == KERNEL_TYPE_NETBSD) 6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF); 6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memaddr = RAW_ADDR (phdr->p_paddr); 6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memsiz = phdr->p_memsz; 6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (memaddr < RAW_ADDR (0x100000)) 6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_BELOW_1MB; 6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* If the memory range contains the entry address, get the 6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project physical address here. */ 6215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (type == KERNEL_TYPE_MULTIBOOT 6225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && (unsigned) entry_addr >= phdr->p_vaddr 6235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && (unsigned) entry_addr < phdr->p_vaddr + memsiz) 6245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project real_entry_addr = (entry_func) ((unsigned) entry_addr 6255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project + memaddr - phdr->p_vaddr); 6265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* make sure we only load what we're supposed to! */ 6285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (filesiz > memsiz) 6295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project filesiz = memsiz; 6305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* mark memory as used */ 6315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (cur_addr < memaddr + memsiz) 6325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = memaddr + memsiz; 6335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz, 6345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memsiz - filesiz); 6355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* increment number of segments */ 6365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project loaded++; 6375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* load the segment */ 6395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (memcheck (memaddr, memsiz) 6405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && grub_read ((char *) memaddr, filesiz) == filesiz) 6415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 6425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (memsiz > filesiz) 6435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memset ((char *) (memaddr + filesiz), 0, memsiz - filesiz); 6445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 6465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 6475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! errnum) 6515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 6525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! loaded) 6535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 6545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 6555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 6565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Load ELF symbols. */ 6575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Elf32_Shdr *shdr = NULL; 6585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int tab_size, sec_size; 6595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int symtab_err = 0; 6605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.num = pu.elf->e_shnum; 6625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.size = pu.elf->e_shentsize; 6635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.shndx = pu.elf->e_shstrndx; 6645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* We should align to a 4K boundary here for good measure. */ 6665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (align_4k) 6675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; 6685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project tab_size = pu.elf->e_shentsize * pu.elf->e_shnum; 6705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_seek (pu.elf->e_shoff); 6725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (grub_read ((char *) RAW_ADDR (cur_addr), tab_size) 6735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project == tab_size) 6745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 6755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.addr = cur_addr; 6765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project shdr = (Elf32_Shdr *) mbi.syms.e.addr; 6775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += tab_size; 6785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (", shtab=0x%x", cur_addr); 6805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < mbi.syms.e.num; i++) 6825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 6835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* This section is a loaded section, 6845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project so we don't care. */ 6855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (shdr[i].sh_addr != 0) 6865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project continue; 6875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* This section is empty, so we don't care. */ 6895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (shdr[i].sh_size == 0) 6905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project continue; 6915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Align the section to a sh_addralign bits boundary. */ 6935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = ((cur_addr + shdr[i].sh_addralign) & 6945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project - (int) shdr[i].sh_addralign); 6955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_seek (shdr[i].sh_offset); 6975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sec_size = shdr[i].sh_size; 6995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! (memcheck (cur_addr, sec_size) 7015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project && (grub_read ((char *) RAW_ADDR (cur_addr), 7025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sec_size) 7035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project == sec_size))) 7045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 7055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project symtab_err = 1; 7065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 7075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project shdr[i].sh_addr = cur_addr; 7105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += sec_size; 7115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project symtab_err = 1; 7155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (mbi.syms.e.addr < RAW_ADDR(0x10000)) 7175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project symtab_err = 1; 7185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (symtab_err) 7205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 7215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf ("(bad)"); 7225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.num = 0; 7235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.size = 0; 7245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.addr = 0; 7255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.syms.e.shndx = 0; 7265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = 0; 7275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.flags |= MB_INFO_ELF_SHDR; 7305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! errnum) 7355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 7365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_printf (", entry=0x%x]\n", (unsigned) entry_addr); 7375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* If the entry address is physically different from that of the ELF 7395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project header, correct it here. */ 7405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (real_entry_addr) 7415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_addr = real_entry_addr; 7425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 7455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project putchar ('\n'); 7465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project type = KERNEL_TYPE_NONE; 7475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 7505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Sanity check. */ 7525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (suggested_type != KERNEL_TYPE_NONE && suggested_type != type) 7535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 7545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project errnum = ERR_EXEC_FORMAT; 7555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return KERNEL_TYPE_NONE; 7565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return type; 7595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 7605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint 7625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectload_module (char *module, char *arg) 7635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 7645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int len; 7655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* if we are supposed to load on 4K boundaries */ 7675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; 7685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!grub_open (module)) 7705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 0; 7715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project len = grub_read ((char *) cur_addr, -1); 7735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! len) 7745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 7755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 7765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 0; 7775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (" [Multiboot-module @ 0x%x, 0x%x bytes]\n", cur_addr, len); 7805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* these two simply need to be set if any modules are loaded at all */ 7825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.flags |= MB_INFO_MODS; 7835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.mods_addr = (int) mll; 7845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mll[mbi.mods_count].cmdline = (int) arg; 7865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mll[mbi.mods_count].mod_start = cur_addr; 7875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_addr += len; 7885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mll[mbi.mods_count].mod_end = cur_addr; 7895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mll[mbi.mods_count].pad = 0; 7905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* increment number of modules included */ 7925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mbi.mods_count++; 7935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 7955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 1; 7965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 7975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint 7995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectload_initrd (char *initrd) 8005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 8015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int len; 8025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned long moveto; 8035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned long max_addr; 8045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct linux_kernel_header *lh 8055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project = (struct linux_kernel_header *) (cur_addr - LINUX_SETUP_MOVE_SIZE); 8065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_DECOMPRESSION 8085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project no_decompression = 1; 8095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 8105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! grub_open (initrd)) 8125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project goto fail; 8135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project len = grub_read ((char *) cur_addr, -1); 8155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (! len) 8165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 8175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 8185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project goto fail; 8195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (linux_mem_size) 8225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project moveto = linux_mem_size; 8235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 8245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project moveto = (mbi.mem_upper + 0x400) << 10; 8255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project moveto = (moveto - len) & 0xfffff000; 8275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203 8285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS); 8295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (moveto + len >= max_addr) 8305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project moveto = (max_addr - len) & 0xfffff000; 8315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid 8335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project the last page. 8345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project XXX: Linux 2.2.xx has a bug in the memory range check, which is 8355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project worse than that of Linux 2.3.xx, so avoid the last 64kb. *sigh* */ 8365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project moveto -= 0x10000; 8375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len); 8385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf (" [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len); 8405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* FIXME: Should check if the kernel supports INITRD. */ 8425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->ramdisk_image = RAW_ADDR (moveto); 8435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lh->ramdisk_size = len; 8445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project grub_close (); 8465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project fail: 8485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_DECOMPRESSION 8505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project no_decompression = 0; 8515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 8525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return ! errnum; 8545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 8555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef GRUB_UTIL 8585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Dummy function to fake the *BSD boot. */ 8595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 8605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectbsd_boot_entry (int flags, int bootdev, int sym_start, int sym_end, 8615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int mem_upper, int mem_lower) 8625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 8635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project stop (); 8645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 8655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 8665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 8695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * All "*_boot" commands depend on the images being loaded into memory 8705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * correctly, the variables in this file being set up correctly, and 8715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the root partition being set in the 'saved_drive' and 'saved_partition' 8725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * variables. 8735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 8745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid 8775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectbsd_boot (kernel_t type, int bootdev, char *arg) 8785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 8795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char *str; 8805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int clval = 0, i; 8815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct bootinfo bi; 8825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef GRUB_UTIL 8845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project entry_addr = (entry_func) bsd_boot_entry; 8855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 8865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project stop_floppy (); 8875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 8885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (*(++arg) && *arg != ' '); 8905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str = arg; 8915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (*str) 8925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 8935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == '-') 8945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 8955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (*str && *str != ' ') 8965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 8975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'C') 8985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_CDROM; 8995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'a') 9005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_ASKNAME; 9015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'b') 9025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_HALT; 9035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'c') 9045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_CONFIG; 9055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'd') 9065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_KDB; 9075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'D') 9085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_MULTIPLE; 9095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'g') 9105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_GDB; 9115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'h') 9125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_SERIAL; 9135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'm') 9145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_MUTE; 9155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'r') 9165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_DFLTROOT; 9175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 's') 9185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_SINGLE; 9195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*str == 'v') 9205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_VERBOSE; 9215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str++; 9225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project continue; 9245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project str++; 9265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (type == KERNEL_TYPE_FREEBSD) 9295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 9305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clval |= RB_BOOTINFO; 9315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_version = BOOTINFO_VERSION; 9335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *arg = 0; 9355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/'); 9365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*arg == '/') 9375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_kernelname = arg + 1; 9385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 9395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_kernelname = 0; 9405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_nfs_diskless = 0; 9425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_n_bios_used = 0; /* this field is apparently unused */ 9435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < N_BIOS_GEOM; i++) 9455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 9465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct geometry geom; 9475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* XXX Should check the return value. */ 9495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project get_diskinfo (i + 0x80, &geom); 9505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* FIXME: If HEADS or SECTORS is greater than 255, then this will 9515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break the geometry information. That is a drawback of BSD 9525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project but not of GRUB. */ 9535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_bios_geom[i] = (((geom.cylinders - 1) << 16) 9545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project + (((geom.heads - 1) & 0xff) << 8) 9555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project + (geom.sectors & 0xff)); 9565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_size = sizeof (struct bootinfo); 9595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_memsizes_valid = 1; 9605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_bios_dev = saved_drive; 9615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_basemem = mbi.mem_lower; 9625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_extmem = extended_memory; 9635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (mbi.flags & MB_INFO_AOUT_SYMS) 9655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 9665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_symtab = mbi.syms.a.addr; 9675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_esymtab = mbi.syms.a.addr + 4 9685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project + mbi.syms.a.tabsize + mbi.syms.a.strsize; 9695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if 0 9715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (mbi.flags & MB_INFO_ELF_SHDR) 9725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 9735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* FIXME: Should check if a symbol table exists and, if exists, 9745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pass the table to BI. */ 9755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 9775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 9785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 9795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_symtab = 0; 9805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project bi.bi_esymtab = 0; 9815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* call entry point */ 9845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (*entry_addr) (clval, bootdev, 0, 0, 0, ((int) (&bi))); 9855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 9875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 9885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 9895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * We now pass the various bootstrap parameters to the loaded 9905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * image via the argument list. 9915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 9925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This is the official list: 9935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 9945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg0 = 8 (magic) 9955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg1 = boot flags 9965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg2 = boot device 9975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg3 = start of symbol table (0 if not loaded) 9985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg4 = end of symbol table (0 if not loaded) 9995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg5 = transfer address from image 10005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg6 = transfer address for next image pointer 10015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg7 = conventional memory size (640) 10025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * arg8 = extended memory size (8196) 10035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 10045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * ...in actuality, we just pass the parameters used by the kernel. 10055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 10065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* call entry point */ 10085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned long end_mark; 10095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (mbi.flags & MB_INFO_AOUT_SYMS) 10115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project end_mark = (mbi.syms.a.addr + 4 10125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project + mbi.syms.a.tabsize + mbi.syms.a.strsize); 10135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 10145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* FIXME: it should be mbi.syms.e.size. */ 10155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project end_mark = 0; 10165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (*entry_addr) (clval, bootdev, 0, end_mark, 10185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project extended_memory, mbi.mem_lower); 10195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 10205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 1021