/[grub]/grub2/loader/powerpc/ieee1275/linux.c
ViewVC logotype

Diff of /grub2/loader/powerpc/ieee1275/linux.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.7 by hollisb, Tue Jun 21 02:33:51 2005 UTC revision 1.8 by hollisb, Tue Jul 12 22:36:43 2005 UTC
# Line 48  grub_linux_boot (void) Line 48  grub_linux_boot (void)
48  {  {
49    kernel_entry_t linuxmain;    kernel_entry_t linuxmain;
50    grub_size_t actual;    grub_size_t actual;
51      
52    /* Set the command line arguments.  */    /* Set the command line arguments.  */
53    grub_ieee1275_set_property (grub_ieee1275_chosen, "bootargs", linux_args,    grub_ieee1275_set_property (grub_ieee1275_chosen, "bootargs", linux_args,
54                                grub_strlen (linux_args) + 1, &actual);                                grub_strlen (linux_args) + 1, &actual);
55      
56      grub_dprintf ("loader", "Entry point: 0x%x\n", linux_addr);
57      grub_dprintf ("loader", "Initrd at: 0x%x, size 0x%x\n", initrd_addr,
58                    initrd_size);
59      grub_dprintf ("loader", "Boot arguments: %s\n", linux_args);
60      grub_dprintf ("loader", "Jumping to Linux...\n");
61    
62    /* Boot the kernel.  */    /* Boot the kernel.  */
63    linuxmain = (kernel_entry_t) linux_addr;    linuxmain = (kernel_entry_t) linux_addr;
64    linuxmain ((void *) initrd_addr, initrd_size, grub_ieee1275_entry_fn, 0, 0);    linuxmain ((void *) initrd_addr, initrd_size, grub_ieee1275_entry_fn, 0, 0);
# Line 65  grub_linux_release_mem (void) Line 71  grub_linux_release_mem (void)
71  {  {
72    grub_free (linux_args);    grub_free (linux_args);
73    linux_args = 0;    linux_args = 0;
74      
75    if (linux_addr && grub_ieee1275_release (linux_addr, linux_size))    if (linux_addr && grub_ieee1275_release (linux_addr, linux_size))
76      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");
77      
78    if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size))    if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size))
79      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");
80      
81    linux_addr = 0;    linux_addr = 0;
82    initrd_addr = 0;    initrd_addr = 0;
83      
84    return GRUB_ERR_NONE;    return GRUB_ERR_NONE;
85  }  }
86    
# Line 82  static grub_err_t Line 88  static grub_err_t
88  grub_linux_unload (void)  grub_linux_unload (void)
89  {  {
90    grub_err_t err;    grub_err_t err;
91      
92    err = grub_linux_release_mem ();    err = grub_linux_release_mem ();
93    grub_dl_unref (my_mod);    grub_dl_unref (my_mod);
94      
95    loaded = 0;    loaded = 0;
96      
97    return err;    return err;
98  }  }
99    
# Line 97  grub_rescue_cmd_linux (int argc, char *a Line 103  grub_rescue_cmd_linux (int argc, char *a
103    grub_file_t file = 0;    grub_file_t file = 0;
104    Elf32_Ehdr ehdr;    Elf32_Ehdr ehdr;
105    Elf32_Phdr *phdrs = 0;    Elf32_Phdr *phdrs = 0;
106    int i;      int i;
107    int offset = 0;    int offset = 0;
108    grub_addr_t entry;    grub_addr_t entry;
109    int found_addr = 0;    int found_addr = 0;
110    int size;    int size;
111      
112    grub_dl_ref (my_mod);    grub_dl_ref (my_mod);
113    
114    if (argc == 0)    if (argc == 0)
# Line 110  grub_rescue_cmd_linux (int argc, char *a Line 116  grub_rescue_cmd_linux (int argc, char *a
116        grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");        grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
117        goto fail;        goto fail;
118      }      }
119      
120    file = grub_file_open (argv[0]);    file = grub_file_open (argv[0]);
121    if (! file)    if (! file)
122      goto fail;      goto fail;
123      
124    if (grub_file_read (file, (char *) &ehdr, sizeof (ehdr)) != sizeof (ehdr))    if (grub_file_read (file, (char *) &ehdr, sizeof (ehdr)) != sizeof (ehdr))
125      {      {
126        grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux elf header");        grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux elf header");
127        goto fail;        goto fail;
128      }      }
129      
130    if (grub_dl_check_header (&ehdr, sizeof(ehdr)))    if (grub_dl_check_header (&ehdr, sizeof(ehdr)))
131      {      {
132        grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");        grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
133        goto fail;        goto fail;
134      }      }
135      
136    if (ehdr.e_type != ET_EXEC)    if (ehdr.e_type != ET_EXEC)
137      {      {
138        grub_error (GRUB_ERR_UNKNOWN_OS,        grub_error (GRUB_ERR_UNKNOWN_OS,
# Line 146  grub_rescue_cmd_linux (int argc, char *a Line 152  grub_rescue_cmd_linux (int argc, char *a
152    
153    phdrs = (Elf32_Phdr *) grub_malloc (ehdr.e_phnum * ehdr.e_phentsize);    phdrs = (Elf32_Phdr *) grub_malloc (ehdr.e_phnum * ehdr.e_phentsize);
154    grub_file_read (file, (void *) phdrs, ehdr.e_phnum * ehdr.e_phentsize);    grub_file_read (file, (void *) phdrs, ehdr.e_phnum * ehdr.e_phentsize);
155      
156    /* Release the previously used memory.  */    /* Release the previously used memory.  */
157    grub_loader_unset ();    grub_loader_unset ();
158      
159    /* Determine the amount of memory that is required.  */    /* Determine the amount of memory that is required.  */
160    linux_size = 0;    linux_size = 0;
161    for (i = 0; i < ehdr.e_phnum; i++)    for (i = 0; i < ehdr.e_phnum; i++)
# Line 158  grub_rescue_cmd_linux (int argc, char *a Line 164  grub_rescue_cmd_linux (int argc, char *a
164        /* XXX: Is this calculation correct?  */        /* XXX: Is this calculation correct?  */
165        linux_size += phdr->p_memsz + phdr->p_filesz;        linux_size += phdr->p_memsz + phdr->p_filesz;
166      }      }
167      
168    /* Reserve memory for the kernel.  */    /* Reserve memory for the kernel.  */
169    linux_size += 0x100000;    linux_size += 0x100000;
170      
171    /* For some vmlinux kernels the address set above won't work.  Just    /* For some vmlinux kernels the address set above won't work.  Just
172       try some other addresses just like yaboot does.  */       try some other addresses just like yaboot does.  */
173    for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000)    for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000)
# Line 177  grub_rescue_cmd_linux (int argc, char *a Line 183  grub_rescue_cmd_linux (int argc, char *a
183        goto fail;        goto fail;
184      }      }
185    entry = linux_addr;    entry = linux_addr;
186      
187    /* Load every loadable segment in memory.  */    /* Load every loadable segment in memory.  */
188    for (i = 0; i < ehdr.e_phnum; i++)    for (i = 0; i < ehdr.e_phnum; i++)
189      {      {
# Line 185  grub_rescue_cmd_linux (int argc, char *a Line 191  grub_rescue_cmd_linux (int argc, char *a
191    
192        if (phdr->p_type == PT_LOAD)        if (phdr->p_type == PT_LOAD)
193          {          {
194              void *segment_addr = ((char *) entry) + offset;
195    
196            if (grub_file_seek (file, phdr->p_offset) == -1)            if (grub_file_seek (file, phdr->p_offset) == -1)
197              {              {
198                grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");                grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
199                goto fail;                goto fail;
200              }              }
201              
202            if (grub_file_read (file, (void *) (((char *) entry) + offset) , phdr->p_filesz)            grub_dprintf ("loader", "Loading segment %d at %p, size 0x%x\n", i,
203                            segment_addr, phdr->p_filesz);
204    
205              if (grub_file_read (file, segment_addr, phdr->p_filesz)
206                != (grub_ssize_t) phdr->p_filesz)                != (grub_ssize_t) phdr->p_filesz)
207              goto fail;              goto fail;
208              
209            if (phdr->p_filesz < phdr->p_memsz)            if (phdr->p_filesz < phdr->p_memsz)
210              grub_memset ((char *) (((char *) entry) + offset) + phdr->p_filesz, 0,              grub_memset ((char *) (((char *) entry) + offset) + phdr->p_filesz, 0,
211                           phdr->p_memsz - phdr->p_filesz);                           phdr->p_memsz - phdr->p_filesz);
212    
213            offset += phdr->p_filesz;            offset += phdr->p_filesz;
214          }          }
215      }      }
216      
217    size = 0;    size = 0;
218    for (i = 0; i < argc; i++)    for (i = 0; i < argc; i++)
219      size += grub_strlen (argv[i]);      size += grub_strlen (argv[i]);
220      
221    linux_args = grub_malloc (size + argc + 1);    linux_args = grub_malloc (size + argc + 1);
222    if (!linux_args)    if (!linux_args)
223      goto fail;      goto fail;
224      
225    for (i = 1; i < argc; i++)    for (i = 1; i < argc; i++)
226      {      {
227        grub_strcat (linux_args, argv[i]);        grub_strcat (linux_args, argv[i]);
228        grub_strcat (linux_args, " ");        grub_strcat (linux_args, " ");
229      }      }
230      
231   fail:   fail:
232    
233    if (file)    if (file)
234      grub_file_close (file);      grub_file_close (file);
235      
236    grub_free (phdrs);    grub_free (phdrs);
237    
238    if (grub_errno != GRUB_ERR_NONE)    if (grub_errno != GRUB_ERR_NONE)
# Line 236  grub_rescue_cmd_linux (int argc, char *a Line 247  grub_rescue_cmd_linux (int argc, char *a
247        initrd_addr = 0;        initrd_addr = 0;
248        loaded = 1;        loaded = 1;
249      }      }
250      
251    return;    return;
252  }  }
253    
# Line 246  grub_rescue_cmd_initrd (int argc, char * Line 257  grub_rescue_cmd_initrd (int argc, char *
257    grub_file_t file = 0;    grub_file_t file = 0;
258    grub_ssize_t size;    grub_ssize_t size;
259    grub_addr_t addr;    grub_addr_t addr;
260      
261    if (argc == 0)    if (argc == 0)
262      {      {
263        grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");        grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
264        goto fail;        goto fail;
265      }      }
266      
267    if (!loaded)    if (!loaded)
268      {      {
269        grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");        grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
# Line 262  grub_rescue_cmd_initrd (int argc, char * Line 273  grub_rescue_cmd_initrd (int argc, char *
273    file = grub_file_open (argv[0]);    file = grub_file_open (argv[0]);
274    if (! file)    if (! file)
275      goto fail;      goto fail;
276      
277    addr = linux_addr + linux_size;    addr = linux_addr + linux_size;
278    size = grub_file_size (file);    size = grub_file_size (file);
279      
280    if (grub_claimmap (addr, size) == -1)    if (grub_claimmap (addr, size) == -1)
281      {      {
282        grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");        grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");
283        goto fail;        goto fail;
284      }      }
285      
286      grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
287    
288    if (grub_file_read (file, (void *) addr, size) != size)    if (grub_file_read (file, (void *) addr, size) != size)
289      {      {
290        grub_ieee1275_release (addr, size);        grub_ieee1275_release (addr, size);
291        grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");        grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
292        goto fail;        goto fail;
293      }      }
294      
295    initrd_addr = addr;    initrd_addr = addr;
296    initrd_size = size;    initrd_size = size;
297      
298   fail:   fail:
299    if (file)    if (file)
300      grub_file_close (file);      grub_file_close (file);

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26