~ubuntu-branches/ubuntu/trusty/apex/trusty

« back to all changes in this revision

Viewing changes to usr/link.cc

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2009-11-10 11:55:15 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091110115515-6jjsf6rc8py35awe
Tags: 1.6.10ubuntu1
* Merge from debian testing, remaining changes:
  - Move apex VMA address to 4MiB to leave enough space for the ubuntu
  kernel and not overwrite apex in ram when loading.
  - nslu2 configuration: set CONFIG_RAMDISK_SIZE=0x0055FFF0 instead of
  0x005FFFF0 to make enough room for ubuntu initramfs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
   Copyright (C) 2007 Marc Singer
7
7
 
8
8
   This program is free software; you can redistribute it and/or
9
 
   modify it under the terms of the GNU General Public License as
10
 
   published by the Free Software Foundation; either version 2 of the
11
 
   License, or (at your option) any later version.
12
 
 
13
 
   This program is distributed in the hope that it will be useful, but
14
 
   WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
   General Public License for more details.
17
 
 
18
 
   You should have received a copy of the GNU General Public License
19
 
   along with this program; if not, write to the Free Software
20
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21
 
   USA.
 
9
   modify it under the terms of the GNU General Public License
 
10
   version 2 as published by the Free Software Foundation.
 
11
   Please refer to the file debian/copyright for further details.
22
12
 
23
13
   -----------
24
14
   DESCRIPTION
183
173
          ++i;
184
174
          break;
185
175
        case 4:
186
 
          printf ("%08x ", *((u32*)&rgb[i]));
 
176
          printf ("%08lx ", *((u32*)&rgb[i]));
187
177
          i += 3;
188
178
          break;
189
179
        }
244
234
 
245
235
  char* pch;
246
236
  if ((pch = index (sz, ':'))) {
247
 
    int c = pch - sz;
248
 
    if (c > sizeof (d.driver) - 1)
 
237
    ssize_t c = pch - sz;
 
238
    if (c > ssize_t (sizeof (d.driver) - 1))
249
239
      c = sizeof (d.driver) - 1;
250
240
    memcpy (d.driver, sz, c);
251
241
    d.driver[c] = 0;
272
262
}
273
263
 
274
264
 
 
265
/* Link::containus_apex
 
266
 
 
267
   scans the MTD partition for APEX.  It returns true if APEX is
 
268
   found.
 
269
 
 
270
*/
 
271
 
 
272
bool Link::contains_apex (const MTDPartition& mtd) const
 
273
{
 
274
  PRINTF ("%s: '%s'\n", __FUNCTION__, mtd.dev_block ());
 
275
  int fh = ::open (mtd.dev_block (), O_RDONLY);
 
276
  if (fh == -1)
 
277
    throw "unable to open mtd device.  Root privileges may be required.";
 
278
 
 
279
  void* pv = mmap (NULL, CB_LINK_SCAN, PROT_READ, MAP_SHARED, fh, 0);
 
280
  if (pv == MAP_FAILED) {
 
281
    ::close (fh);
 
282
    throw "failed to mmap on open_apex";
 
283
  }
 
284
 
 
285
  int env_link_version = 0;
 
286
  bool fFound = false;
 
287
 
 
288
  {
 
289
    unsigned long* rgl = (unsigned long*) pv;
 
290
    for (size_t i = 0;
 
291
         i < CB_LINK_SCAN/sizeof (unsigned long)
 
292
           - sizeof (env_link)/sizeof (unsigned long);
 
293
         ++i) {
 
294
//      printf ("%d 0x%x (%x %x)\n",
 
295
//            i, rgl[i], ENV_LINK_MAGIC, swab32 (ENV_LINK_MAGIC));
 
296
 
 
297
      switch (rgl[i]) {
 
298
      case ENV_LINK_MAGIC_1:
 
299
        env_link_version = 1;
 
300
        break;
 
301
      case ENV_LINK_MAGIC:
 
302
        env_link_version = 2;
 
303
        break;
 
304
      }
 
305
 
 
306
      switch (swab32 (rgl[i])) {
 
307
      case ENV_LINK_MAGIC_1:
 
308
//      endian_mismatch = true;
 
309
        env_link_version = 1;
 
310
        break;
 
311
      case ENV_LINK_MAGIC:
 
312
//      endian_mismatch = true;
 
313
        env_link_version = 2;
 
314
        break;
 
315
      }
 
316
 
 
317
      if (!env_link_version)
 
318
        continue;
 
319
 
 
320
      fFound = true;
 
321
      break;
 
322
    }
 
323
  }
 
324
 
 
325
  munmap (pv, CB_LINK_SCAN);
 
326
  close (fh);
 
327
 
 
328
  return fFound;
 
329
}
 
330
 
 
331
 
275
332
/* Link::open
276
333
 
277
334
   opens the link by locating APEX, copying the loader, generating a
340
397
}
341
398
 
342
399
 
 
400
/* Link::locate
 
401
 
 
402
   searches the MTD partitions for APEX.  The return value is the name
 
403
   of the partition.
 
404
 
 
405
   Note that this function returns an allocated pointer.  On the one
 
406
   hand, this is a memory leak.  However, it is unnecessary to worry
 
407
   about it since this is a short-running program.
 
408
 
 
409
*/
 
410
 
 
411
const MTDPartition Link::locate (void) const
 
412
{
 
413
        // First, look for the loader by the name of the partition
 
414
  MTDPartition mtd = MTDPartition::find ("Loader");
 
415
 
 
416
  if (!mtd.is () || !contains_apex (mtd))
 
417
    for (mtd = MTDPartition::first (); mtd.is (); mtd = mtd.next ())
 
418
      if (contains_apex (mtd))
 
419
        break;
 
420
 
 
421
  return mtd;
 
422
}
 
423
 
 
424
 
343
425
/* Link::map_environment
344
426
 
345
427
   locates the user-modifiable environment in flash and maps it.
411
493
 
412
494
  {
413
495
    unsigned long* rgl = (unsigned long*) pv;
414
 
    for (int i = 0;
 
496
    for (size_t i = 0;
415
497
         i < CB_LINK_SCAN/sizeof (unsigned long)
416
498
           - sizeof (env_link)/sizeof (unsigned long);
417
499
         ++i) {
418
 
      //      printf ("%d 0x%x (%x %x)\n",
419
 
      //              i, rgl[i], ENV_LINK_MAGIC, swab32 (ENV_LINK_MAGIC));
 
500
//      printf ("%d 0x%x (%x %x)\n",
 
501
//            i, rgl[i], ENV_LINK_MAGIC, swab32 (ENV_LINK_MAGIC));
420
502
 
421
503
      switch (rgl[i]) {
422
504
      case ENV_LINK_MAGIC_1:
478
560
 
479
561
  int cbLink = (sizeof (struct env_link) + 1024 + 4096 - 1) & ~4096;
480
562
  env_link = (struct env_link*) new char[cbLink];
 
563
  bzero (env_link, cbLink);
481
564
 
482
565
  switch (env_link_version) {
483
566
  case 1:
484
567
    {
485
568
      const struct env_link_1& env_link_1
486
569
        = *(const struct env_link_1*) ((unsigned char*) pv + index_env_link);
487
 
      env_link->magic = env_link_1.magic;
488
 
      env_link->apex_start = env_link_1.apex_start;
489
 
      env_link->apex_end = env_link_1.apex_end;
490
 
      env_link->env_start = env_link_1.env_start;
491
 
      env_link->env_end = env_link_1.env_end;
 
570
      env_link->magic           = env_link_1.magic;
 
571
      env_link->apex_start      = env_link_1.apex_start;
 
572
      env_link->apex_end        = env_link_1.apex_end;
 
573
      env_link->env_start       = env_link_1.env_start;
 
574
      env_link->env_end         = env_link_1.env_end;
492
575
      env_link->env_link        // *** Hack to accomodate partition w/swap
493
576
        = (void*) swab32_maybe (swab32_maybe ((u32) env_link->apex_start)
494
577
                                + index_env_link - 16);
495
 
      env_link->env_d_size = env_link_1.env_d_size;
 
578
      env_link->env_d_size      = env_link_1.env_d_size;
496
579
      memcpy ((void*) env_link->region, env_link_1.region,
497
580
              cbLink - sizeof (struct env_link));
498
581
    }
508
591
  mapping_offset = index_env_link
509
592
    - ((char*) env_link->env_link - (char*) env_link->apex_start);
510
593
 
511
 
  // *** FIXME: due to mapping_offset it could be the case that we
512
 
  // haven't mapped enough of APEX.
 
594
// *** FIXME: due to mapping_offset it could be the case that we
 
595
// haven't mapped enough of APEX.
513
596
  pvApex = (void*) new char[cbApex];
514
597
  memcpy (pvApex, (const char*) pv + mapping_offset, cbApex);
515
598
 
520
603
  memcpy (pvApexSwab, pvApex, cbApex);
521
604
  swab32_block_maybe (pvApexSwab, cbApex);
522
605
 
 
606
                                // Guarantee termination
 
607
  *(char*) &env_link->apexversion[sizeof (env_link->apexversion) - 1] = 0;
 
608
 
523
609
  return true;
524
610
}
525
611
 
543
629
  entries->clear ();
544
630
  idNext = 0;
545
631
 
546
 
  if (pb[0] == 0xff && pb[1] == 0xff) {
 
632
  if (pb[0] == (char)0xff && pb[1] == (char)0xff) {
547
633
    PRINTF ("# empty environment\n");
548
634
    m_state = envEmpty;
549
635
    return entries->size ();
560
646
  pb += 2;
561
647
 
562
648
  const char* pbEnd = pb + cbEnv;
563
 
  while (pb < pbEnd && *pb != 0xff) {
 
649
  while (pb < pbEnd && *pb != (char) 0xff) {
564
650
    const char* head = pb;
565
651
    char flags = *pb++;
566
652
    int id = (unsigned char) flags & 0x7f;
640
726
  memset (rgb, 0xff, sizeof (rgb));
641
727
 
642
728
  if (   ::lseek (fhEnvBlock, ibEnv, SEEK_SET) != ibEnv
643
 
      || ::write (fhEnvBlock, rgb, cbEnv) != cbEnv)
 
729
      || ::write (fhEnvBlock, rgb, cbEnv)      != off_t (cbEnv))
644
730
      throw "failed to write environment";
645
731
}
646
732
 
759
845
  }
760
846
 
761
847
  if (it != entries->end ()) {
762
 
    int cb = strlen (value);
 
848
    size_t cb = strlen (value);
763
849
    if (cbEnv - cbEnvUsed < cb + 2)
764
850
      throw "insufficient free space in environment";
765
851
    *pb++ = 0x80 + (*it).first;
766
852
    memcpy (pb, value, cb + 1);
767
853
    pb += cb + 1;
768
 
    if (::lseek (fhEnvChar, ibEnv + cbEnvUsed, SEEK_SET) != ibEnv + cbEnvUsed
 
854
    if (   ::lseek (fhEnvChar, ibEnv + cbEnvUsed, SEEK_SET) != off_t (ibEnv + cbEnvUsed)
769
855
        || ::write (fhEnvChar, rgb, pb - rgb) != pb - rgb)
770
856
      throw "failed to write environment";
771
857
  }
772
858
  else {
773
 
    int cbKey = strlen (key);
 
859
    size_t cbKey = strlen (key);
774
860
    int cbValue = strlen (value);
775
861
    if (cbEnv - cbEnvUsed < cbKey + cbValue + 3)
776
862
      throw "insufficient free space in environment";
779
865
    pb += cbKey + 1;
780
866
    memcpy (pb, value, cbValue + 1);
781
867
    pb += cbValue + 1;
782
 
    if (::lseek (fhEnvChar, ibEnv + cbEnvUsed, SEEK_SET) != ibEnv + cbEnvUsed
 
868
    if (   ::lseek (fhEnvChar, ibEnv + cbEnvUsed, SEEK_SET)
 
869
             != off_t (ibEnv + cbEnvUsed)
783
870
        || ::write (fhEnvChar, rgb, pb - rgb)
784
871
        != pb - rgb)
785
872
      throw "failed to write environment";