From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1aUL5E-000548-O1 for mharc-grub-devel@gnu.org; Fri, 12 Feb 2016 16:16:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43589) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aUL5B-00053W-7k for grub-devel@gnu.org; Fri, 12 Feb 2016 16:16:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aUL58-0000Pr-Jf for grub-devel@gnu.org; Fri, 12 Feb 2016 16:16:53 -0500 Received: from mail-wm0-x229.google.com ([2a00:1450:400c:c09::229]:36498) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aUL58-0000Pn-4W for grub-devel@gnu.org; Fri, 12 Feb 2016 16:16:50 -0500 Received: by mail-wm0-x229.google.com with SMTP id p63so38067643wmp.1 for ; Fri, 12 Feb 2016 13:16:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type; bh=qHCVm7xQ+vntGqNsj4W66UIztMxpym4dCMEY+r56Ynw=; b=Y4Rm3rVWxc/wLqp5xB/Ye+oaSX67+2+ME4+qDDWTYYhjDPCaeY/9hmzEMYBfOFrf4l C93UvEp8fuvqtlb5YqJ/EQEsBEe2N58JlPcv/2rGyQqIsJ6EkRSNyXJhaeUL3oepe4y9 FqSTH7aSYcoLyr1gT8N8nKmVCXvSYy0LYfbPM8ScB6xsWQe7hMWY6O0urE9yzSjqJ8QK jL2Pn4iHaks7Cz30LSPbgSGbqQJo3LtiAZbAxhU6xo6C3F0z5DqMc5MWgIbgVehuPG21 cN5FTVXYpF9iXM9sUQ57J+A5oEt9BXVhr/1pVkzs7pQvAIgDTTlG8zge4GXi5uDgU6BM Pf3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-type; bh=qHCVm7xQ+vntGqNsj4W66UIztMxpym4dCMEY+r56Ynw=; b=FzXLV/zNlsCNKXRrFs3YVUMsTWGsxXsWRtNru7bxmx0BtrRdFSvhJltIIOvSjFstOp QovvzMdk+GpEymzAwqKHiBeDTfCwUcPavwfzAMgqUsqDJvW18z1SS4mKlakhI2AznCzE +kBbFzumn1PE9yu5RrR9kJYKh27xK+vWxpjG3/Gu5RKMiwDCZQWyritIQzAM5KI9vhM/ p4zWLJ2dZmJsBdblGEO42I89I1gHfcPyaAe7b83eKA2tbtoUljLqX2d4GcSNzRv+/YvT jOKYqxLZZcAIU9oUHayFzI9L9/67c5AUnP4PQGfKhER9dmE9SCNHT+9WVLaFupXv1ZHx GJww== X-Gm-Message-State: AG10YOSxTUJ6+oLMjFthSCkjSaaOVA82ibWBD1By8sCDHGtGNqqKTz8ROOAoa66JezsK1g== X-Received: by 10.28.60.84 with SMTP id j81mr6656560wma.91.1455311809593; Fri, 12 Feb 2016 13:16:49 -0800 (PST) Received: from ?IPv6:2a02:120b:2c41:63f0:a2a8:cdff:fe64:b3b5? ([2a02:120b:2c41:63f0:a2a8:cdff:fe64:b3b5]) by smtp.gmail.com with ESMTPSA id t12sm3977641wmt.20.2016.02.12.13.16.48 for (version=TLSv1/SSLv3 cipher=OTHER); Fri, 12 Feb 2016 13:16:48 -0800 (PST) Subject: Re: [PATCH v3 2/3] i386: Add support for loading from android bootimg To: The development of GNU GRUB References: <1454964459-28213-1-git-send-email-shea@shealevy.com> <1454964459-28213-3-git-send-email-shea@shealevy.com> <56BE1B60.5060900@gmail.com> <7384a36941a77cced1fde7e3d084280a@shealevy.com> <2b7ecf3a0dda2687029878e0e745bd73@shealevy.com> From: =?UTF-8?Q?Vladimir_'=cf=86-coder/phcoder'_Serbinenko?= Message-ID: <56BE4BB7.6040203@gmail.com> Date: Fri, 12 Feb 2016 22:16:39 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Icedove/38.5.0 MIME-Version: 1.0 In-Reply-To: <2b7ecf3a0dda2687029878e0e745bd73@shealevy.com> Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="KavqXwsdmoEEcJV31R712njljAciSMaQD" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::229 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Feb 2016 21:16:55 -0000 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --KavqXwsdmoEEcJV31R712njljAciSMaQD Content-Type: multipart/mixed; boundary="------------010105020402060508000705" This is a multi-part message in MIME format. --------------010105020402060508000705 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 12.02.2016 20:34, Shea Levy wrote: > OK. Do you have any thoughts on how best to extract the "load the kerne= l > and set the command line to a specific string" functionality out of the= > linux command, then? >=20 At first I wanted to write a short skeleton patch to show what I meant but once skeleton is done, there is little actual code involved. Please try attached patch > On 2016-02-12 14:22, Vladimir 'phcoder' Serbinenko wrote: >> Separate command is better as it keeps interface tidy and unpoluted, >> decreasing maintenance cost. Correct me if I'm wrong but it should be >> clear from context of file is Android image or usual linux one? >> >> Le ven. 12 f=C3=A9vr. 2016 20:19, Shea Levy a =C3=A9= crit : >> >>> On 2016-02-12 12:50, Vladimir '=CF=86-coder/phcoder' Serbinenko wrote= : >>> > On 08.02.2016 21:47, Shea Levy wrote: >>> >> --- >>> >> grub-core/loader/i386/linux.c | 27 +++++++++++++++++++++------ >>> >> 1 file changed, 21 insertions(+), 6 deletions(-) >>> >> >>> >> diff --git a/grub-core/loader/i386/linux.c >>> >> b/grub-core/loader/i386/linux.c >>> >> index fddcc46..6ab8d3c 100644 >>> >> --- a/grub-core/loader/i386/linux.c >>> >> +++ b/grub-core/loader/i386/linux.c >>> >> @@ -35,6 +35,7 @@ >>> >> #include >>> >> #include >>> >> #include >>> >> +#include >>> >> >>> >> GRUB_MOD_LICENSE ("GPLv3+"); >>> >> >>> >> @@ -695,7 +696,13 @@ grub_cmd_linux (grub_command_t cmd >>> >> __attribute__ ((unused)), >>> >> goto fail; >>> >> } >>> >> >>> >> - file =3D grub_file_open (argv[0]); >>> >> + char android_cmdline[BOOT_ARGS_SIZE]; >>> >> + android_cmdline[0] =3D ''; >>> >> + if (grub_memcmp (argv[0], "android_bootimg:", sizeof >>> >> "android_bootimg:" - 1) =3D=3D 0) >>> >> + grub_android_bootimg_load_kernel (argv[0] + sizeof >>> >> "android_bootimg:" - 1, >>> >> + &file, android_cmdline); >>> >> + else >>> >> + file =3D grub_file_open (argv[0]); >>> > I hoped more for autodetection. This gets a bit hairy and proper >>> > separation is better. Sorry for confusion. I think it's simpler wit= h >>> > commands like >>> > android_bootimg [--no-cmdline] [--no-initrd] IMAGE [EXTRA_ARGUMENTS= ] >>> > by default it will load both IMAGE, with cmdline and initrd. With >>> > --no-initrd you can use initrd for custom initrd. >>> >>> Autodetection would be possible actually, I didn't think of that. If >>> grub_file_open fails, we can try grub_android_bootimg_load_kernel on = the >>> same file. Would that be preferable or do we still want a separate >>> command? >>> >>> > >>> >> if (! file) >>> >> goto fail; >>> >> >>> >> @@ -1008,12 +1015,20 @@ grub_cmd_linux (grub_command_t cmd >>> >> __attribute__ ((unused)), >>> >> linux_cmdline =3D grub_zalloc (maximal_cmdline_size + 1); >>> >> if (!linux_cmdline) >>> >> goto fail; >>> >> - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));= >>> >> + grub_size_t cmdline_offset =3D 0; >>> >> + if (android_cmdline[0]) >>> >> + { >>> >> + cmdline_offset =3D grub_strlen (android_cmdline) + 1; >>> >> + grub_memcpy (linux_cmdline, android_cmdline, cmdline_offset= - >>> >> 1); >>> >> + linux_cmdline[cmdline_offset - 1] =3D ' '; >>> >> + } >>> >> + grub_memcpy (linux_cmdline + cmdline_offset, LINUX_IMAGE, sizeo= f >>> >> (LINUX_IMAGE)); >>> >> + cmdline_offset +=3D sizeof LINUX_IMAGE - 1; >>> > LINUX_IMAGE must be at the beginning. don't forget brackets around >>> > sizeof. >>> >> grub_create_loader_cmdline (argc, argv, >>> >> - linux_cmdline >>> >> - + sizeof (LINUX_IMAGE) - 1, >>> >> - maximal_cmdline_size >>> >> - - (sizeof (LINUX_IMAGE) - 1)); >>> >> + linux_cmdline >>> >> + + cmdline_offset, >>> >> + maximal_cmdline_size >>> >> + - cmdline_offset); >>> >> >>> >> len =3D prot_file_size; >>> >> if (grub_file_read (file, prot_mode_mem, len) !=3D len && >>> >> !grub_errno) >>> >> >>> > >>> > >>> > >>> > _______________________________________________ >>> > Grub-devel mailing list >>> > Grub-devel@gnu.org >>> > https://lists.gnu.org/mailman/listinfo/grub-devel [1] >>> >>> _______________________________________________ >>> Grub-devel mailing list >>> Grub-devel@gnu.org >>> https://lists.gnu.org/mailman/listinfo/grub-devel [1] >> >> >> Links: >> ------ >> [1] https://lists.gnu.org/mailman/listinfo/grub-devel >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> https://lists.gnu.org/mailman/listinfo/grub-devel >=20 >=20 > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel --------------010105020402060508000705 Content-Type: text/x-diff; name="android.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="android.diff" diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.= c index fddcc46..d3870ae 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -35,6 +35,7 @@ #include #include #include +#include =20 GRUB_MOD_LICENSE ("GPLv3+"); =20 @@ -673,11 +674,11 @@ grub_linux_unload (void) return GRUB_ERR_NONE; } =20 + static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) +linux_load (grub_file_t file, grub_off_t fileoffset, grub_off_t filesize= , + const char *extra_cmdline, int argc, char *argv[]) { - grub_file_t file =3D 0; struct linux_kernel_header lh; grub_uint8_t setup_sects; grub_size_t real_size, prot_size, prot_file_size; @@ -689,15 +690,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((u= nused)), =20 grub_dl_ref (my_mod); =20 - if (argc =3D=3D 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file =3D grub_file_open (argv[0]); - if (! file) - goto fail; + grub_file_seek (file, fileoffset); =20 if (grub_file_read (file, &lh, sizeof (lh)) !=3D sizeof (lh)) { @@ -757,7 +750,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((un= used)), setup_sects =3D GRUB_LINUX_DEFAULT_SETUP_SECTS; =20 real_size =3D setup_sects << GRUB_DISK_SECTOR_BITS; - prot_file_size =3D grub_file_size (file) - real_size - GRUB_DISK_SECTO= R_SIZE; + prot_file_size =3D filesize - real_size - GRUB_DISK_SECTOR_SIZE; =20 if (grub_le_to_cpu16 (lh.version) >=3D 0x205 && lh.kernel_alignment !=3D 0 @@ -871,7 +864,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((un= used)), =20 /* The other parameters are filled when booting. */ =20 - grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); + grub_file_seek (file, fileoffset + real_size + GRUB_DISK_SECTOR_SIZE);= =20 grub_dprintf ("linux", "bzImage, setup=3D0x%x, size=3D0x%x\n", (unsigned) real_size, (unsigned) prot_size); @@ -1008,12 +1001,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ = ((unused)), linux_cmdline =3D grub_zalloc (maximal_cmdline_size + 1); if (!linux_cmdline) goto fail; - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_cmdline - + sizeof (LINUX_IMAGE) - 1, - maximal_cmdline_size - - (sizeof (LINUX_IMAGE) - 1)); + char *cmdline_ptr =3D linux_cmdline; + char *cmdline_ptr_end =3D linux_cmdline + maximal_cmdline_size; + /* Construct BOOT_IMAGE=3D/boot/... */ + cmdline_ptr =3D grub_stpcpy (cmdline_ptr, LINUX_IMAGE); + grub_create_loader_cmdline (1, argv, cmdline_ptr, + cmdline_ptr_end - cmdline_ptr); + cmdline_ptr +=3D grub_strlen (cmdline_ptr); + /* Extra */ + if (cmdline_ptr < cmdline_ptr_end - 1 && *extra_cmdline) + { + *cmdline_ptr++ =3D ' '; + cmdline_ptr =3D grub_stpncpy (cmdline_ptr, extra_cmdline, + cmdline_ptr_end - cmdline_ptr); + } + + /* Rest of command line. */ + if (cmdline_ptr < cmdline_ptr_end - 1 && argc > 1) + { + *cmdline_ptr++ =3D ' '; + grub_create_loader_cmdline (argc - 1, argv + 1, cmdline_ptr, + cmdline_ptr_end - cmdline_ptr); + } + else + { + *cmdline_ptr =3D '\0'; + } =20 len =3D prot_file_size; if (grub_file_read (file, prot_mode_mem, len) !=3D len && !grub_errno)= @@ -1029,9 +1042,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((= unused)), =20 fail: =20 - if (file) - grub_file_close (file); - if (grub_errno !=3D GRUB_ERR_NONE) { grub_dl_unref (my_mod); @@ -1042,31 +1052,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ = ((unused)), } =20 static grub_err_t -grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) { - grub_size_t size =3D 0, aligned_size =3D 0; - grub_addr_t addr_min, addr_max; - grub_addr_t addr; + grub_file_t file =3D 0; grub_err_t err; - struct grub_linux_initrd_context initrd_ctx =3D { 0, 0, 0 }; - if (argc =3D=3D 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); =20 - if (! loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel= first")); - goto fail; - } + file =3D grub_file_open (argv[0]); + if (! file) + return grub_errno; =20 - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; + err =3D linux_load (file, 0, grub_file_size (file), "", argc, argv); + grub_file_close (file); + return err; +} + +static grub_err_t +load_initrd (struct grub_linux_initrd_context *initrd_ctx, char *filenam= es[]) +{ + grub_size_t size =3D 0, aligned_size =3D 0; + grub_addr_t addr_min, addr_max; + grub_addr_t addr; + grub_err_t err; =20 - size =3D grub_get_initrd_size (&initrd_ctx); + size =3D grub_get_initrd_size (initrd_ctx); aligned_size =3D ALIGN_UP (size, 4096); =20 /* Get the highest address available for the initrd. */ @@ -1098,10 +1109,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ = ((unused)), addr =3D (addr_max - aligned_size) & ~0xFFF; =20 if (addr < addr_min) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big"); - goto fail; - } + return grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big"); =20 { grub_relocator_chunk_t ch; @@ -1116,8 +1124,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ (= (unused)), initrd_mem_target =3D get_physical_target_address (ch); } =20 - if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) - goto fail; + err =3D grub_initrd_load (initrd_ctx, filenames, initrd_mem); + if (err) + return err; =20 grub_dprintf ("linux", "Initrd, addr=3D0x%x, size=3D0x%x\n", (unsigned) addr, (unsigned) size); @@ -1126,18 +1135,123 @@ grub_cmd_initrd (grub_command_t cmd __attribute_= _ ((unused)), linux_params.ramdisk_size =3D size; linux_params.root_dev =3D 0x0100; /* XXX */ =20 - fail: + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + struct grub_linux_initrd_context initrd_ctx =3D { 0, 0, 0 }; + grub_err_t err; + + if (argc =3D=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + if (! loaded) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the k= ernel first")); + + err =3D grub_initrd_init (argc, argv, &initrd_ctx); + + if (!err) + err =3D load_initrd (&initrd_ctx, argv); + grub_initrd_close (&initrd_ctx); =20 + return err; +} + +static grub_err_t +grub_cmd_android_bootimg (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file =3D 0; + grub_err_t err =3D GRUB_ERR_NONE; + int do_load_initrd =3D 1, do_load_cmdline =3D 1; + struct grub_android_boot_img_hdr boot_img_header; + char *cmdline =3D NULL; + + for (; argc > 0; argc--, argv++) + { + if (grub_strcmp (argv[0], "--no-cmdline") =3D=3D 0) + { + do_load_cmdline =3D 0; + continue; + } + if (grub_strcmp (argv[0], "--no-initrd") =3D=3D 0) + { + do_load_initrd =3D 0; + continue; + } + break; + } + =20 + if (argc =3D=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + file =3D grub_file_open (argv[0]); + if (! file) + return grub_errno; + + if (grub_file_read (file, &boot_img_header, sizeof (boot_img_header)) = !=3D sizeof (boot_img_header)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + err =3D grub_errno; + goto fail; + } + + if (grub_memcmp (boot_img_header.magic, GRUB_ANDROID_BOOT_MAGIC, GRUB_= ANDROID_BOOT_MAGIC_SIZE) !=3D 0) + { + err =3D grub_error (GRUB_ERR_BAD_OS, "invalid android magic"); + goto fail; + } + + if (do_load_cmdline) + { + cmdline =3D grub_malloc (GRUB_ANDROID_BOOT_EXTRA_ARGS_SIZE + + GRUB_ANDROID_BOOT_ARGS_SIZE + 1); + if (!cmdline) + goto fail; + grub_memcpy (cmdline, boot_img_header.cmdline, GRUB_ANDROID_BOOT_A= RGS_SIZE); + grub_memcpy (cmdline + GRUB_ANDROID_BOOT_ARGS_SIZE, boot_img_heade= r.extra_cmdline, GRUB_ANDROID_BOOT_EXTRA_ARGS_SIZE); + cmdline[GRUB_ANDROID_BOOT_EXTRA_ARGS_SIZE + GRUB_ANDROID_BOOT_ARGS= _SIZE] =3D '\0'; + } + + err =3D linux_load (file, boot_img_header.page_size, boot_img_header.k= ernel_size, cmdline ? : "", argc, argv); + if (err) + goto fail; + + if (do_load_initrd && boot_img_header.ramdisk_size) + { + struct grub_linux_initrd_component component =3D { + .size =3D boot_img_header.ramdisk_size, + .newc_name =3D 0, + .file =3D file, + .fileoffset =3D ALIGN_UP (boot_img_header.kernel_size, boot_img_header.= page_size) + }; + struct grub_linux_initrd_context initrd_ctx =3D { + .nfiles =3D 1, + .size =3D boot_img_header.ramdisk_size, + .components =3D &component + }; + err =3D load_initrd (&initrd_ctx, argv); + } + fail: + grub_file_close (file); return grub_errno; } =20 -static grub_command_t cmd_linux, cmd_initrd; + +static grub_command_t cmd_linux, cmd_initrd, cmd_android_bootimg; =20 GRUB_MOD_INIT(linux) { cmd_linux =3D grub_register_command ("linux", grub_cmd_linux, 0, N_("Load Linux.")); + cmd_android_bootimg =3D grub_register_command ("android_bootimg", grub= _cmd_android_bootimg, + "[--no-initrd] [--no-cmdline] IMAGE [OPTIONS]", N_("Load And= roid bootimg.")); cmd_initrd =3D grub_register_command ("initrd", grub_cmd_initrd, 0, N_("Load initrd.")); my_mod =3D mod; @@ -1147,4 +1261,5 @@ GRUB_MOD_FINI(linux) { grub_unregister_command (cmd_linux); grub_unregister_command (cmd_initrd); + grub_unregister_command (cmd_android_bootimg); } diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c index be6fa0f..dea0299 100644 --- a/grub-core/loader/linux.c +++ b/grub-core/loader/linux.c @@ -23,13 +23,6 @@ struct newc_head char check[8]; } GRUB_PACKED; =20 -struct grub_linux_initrd_component -{ - grub_file_t file; - char *newc_name; - grub_off_t size; -}; - struct dir { char *name; @@ -208,6 +201,7 @@ grub_initrd_init (int argc, char *argv[], initrd_ctx->nfiles++; initrd_ctx->components[i].size =3D grub_file_size (initrd_ctx->components[i].file); + initrd_ctx->components[i].fileoffset =3D 0; initrd_ctx->size +=3D initrd_ctx->components[i].size; } =20 @@ -279,6 +273,8 @@ grub_initrd_load (struct grub_linux_initrd_context *i= nitrd_ctx, } =20 cursize =3D initrd_ctx->components[i].size; + grub_file_seek (initrd_ctx->components[i].file, + initrd_ctx->components[i].fileoffset); if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) !=3D cursize) { diff --git a/include/grub/android.h b/include/grub/android.h new file mode 100644 index 0000000..7cd25f4 --- /dev/null +++ b/include/grub/android.h @@ -0,0 +1,73 @@ +/* tools/mkbootimg/bootimg.h +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License");=20 +** you may not use this file except in compliance with the License.=20 +** You may obtain a copy of the License at=20 +** +** http://www.apache.org/licenses/LICENSE-2.0=20 +** +** Unless required by applicable law or agreed to in writing, software=20 +** distributed under the License is distributed on an "AS IS" BASIS,=20 +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli= ed.=20 +** See the License for the specific language governing permissions and=20 +** limitations under the License. +*/ +#ifndef _GRUB_ANDROID_BOOT_IMAGE_H_ +#define _GRUB_ANDROID_BOOT_IMAGE_H_ + +#include + +#define GRUB_ANDROID_BOOT_MAGIC "ANDROID!" +#define GRUB_ANDROID_BOOT_MAGIC_SIZE 8 +#define GRUB_ANDROID_BOOT_NAME_SIZE 16 +#define GRUB_ANDROID_BOOT_ARGS_SIZE 512 +#define GRUB_ANDROID_BOOT_EXTRA_ARGS_SIZE 1024 +struct grub_android_boot_img_hdr +{ + grub_uint8_t magic[GRUB_ANDROID_BOOT_MAGIC_SIZE]; + grub_uint32_t kernel_size; /* size in bytes */ + grub_uint32_t kernel_addr; /* physical load addr */ + grub_uint32_t ramdisk_size; /* size in bytes */ + grub_uint32_t ramdisk_addr; /* physical load addr */ + grub_uint32_t second_size; /* size in bytes */ + grub_uint32_t second_addr; /* physical load addr */ + grub_uint32_t tags_addr; /* physical addr for kernel tags */ + grub_uint32_t page_size; /* flash page size we assume */ + grub_uint32_t unused[2]; /* future expansion: should be 0 */ + grub_uint8_t name[GRUB_ANDROID_BOOT_NAME_SIZE]; /* asciiz product na= me */ + grub_uint8_t cmdline[GRUB_ANDROID_BOOT_ARGS_SIZE]; + grub_uint32_t id[8]; /* timestamp / checksum / sha1 / etc */ + /* Supplemental command line data; kept here to maintain + * binary compatibility with older versions of mkbootimg */ + grub_uint8_t extra_cmdline[GRUB_ANDROID_BOOT_EXTRA_ARGS_SIZE]; +} __attribute__((packed)); +/* +** +-----------------+=20 +** | boot header | 1 page +** +-----------------+ +** | kernel | n pages =20 +** +-----------------+ +** | ramdisk | m pages =20 +** +-----------------+ +** | second stage | o pages +** +-----------------+ +** +** n =3D (kernel_size + page_size - 1) / page_size +** m =3D (ramdisk_size + page_size - 1) / page_size +** o =3D (second_size + page_size - 1) / page_size +** +** 0. all entities are page_size aligned in flash +** 1. kernel and ramdisk are required (size !=3D 0) +** 2. second is optional (second_size =3D=3D 0 -> no second) +** 3. load each element (kernel, ramdisk, second) at +** the specified physical address (kernel_addr, etc) +** 4. prepare tags at tag_addr. kernel_args[] is +** appended to the kernel commandline in the tags. +** 5. r0 =3D 0, r1 =3D MACHINE_TYPE, r2 =3D tags_addr +** 6. if second_size !=3D 0: jump to second_addr +** else: jump to kernel_addr +*/ + +#endif diff --git a/include/grub/linux.h b/include/grub/linux.h index 594a3f3..4a99d78 100644 --- a/include/grub/linux.h +++ b/include/grub/linux.h @@ -9,6 +9,14 @@ struct grub_linux_initrd_context grub_size_t size; }; =20 +struct grub_linux_initrd_component +{ + grub_file_t file; + char *newc_name; + grub_off_t fileoffset; + grub_off_t size; +}; + grub_err_t grub_initrd_init (int argc, char *argv[], struct grub_linux_initrd_context *ctx); diff --git a/include/grub/misc.h b/include/grub/misc.h index 2a9f87c..ef9c9b6 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -64,6 +64,17 @@ grub_stpcpy (char *dest, const char *src) return d - 1; } =20 +static inline char * +grub_stpncpy (char *dest, const char *src, int c) +{ + char *p =3D dest; + + while ((*p++ =3D *src++) !=3D '\0' && --c) + ; + + return p - 1; +} + /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ static inline void * grub_memcpy (void *dest, const void *src, grub_size_t n) --------------010105020402060508000705-- --KavqXwsdmoEEcJV31R712njljAciSMaQD Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iF4EAREKAAYFAla+S78ACgkQmBXlbbo5nOuAHwD/Y3b+wjephitp5Cn1DsOWRaXw HTNgHqBvWq1m2Wm9Ol4A/R46Si3u4IMr+aozICwtv5O0jWJoc2pFdlll66OwhsFs =vvmr -----END PGP SIGNATURE----- --KavqXwsdmoEEcJV31R712njljAciSMaQD--