16f3961507e73f90cec665896dece884e86be560aBill Richardson/* Copyright 2012 The Chromium OS Authors. All rights reserved.
246186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry * Use of this source code is governed by a BSD-style license that can be
346186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry * found in the LICENSE file.
446186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry *
546186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry * Exports the kernel commandline from a given partition/image.
646186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry */
746186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry
817f8d341099120da78a6ca71165834eefb0960edRandall Spangler#include <getopt.h>
946186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry#include <stdio.h>
1046186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry#include <sys/mman.h>
1117f8d341099120da78a6ca71165834eefb0960edRandall Spangler#include <unistd.h>
1246186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry
136f3961507e73f90cec665896dece884e86be560aBill Richardson#include "futility.h"
140c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "vboot_host.h"
152c0711bf540cbbf71c7fe620f1c8290c67fd5accChe-Liang Chiou
1617f8d341099120da78a6ca71165834eefb0960edRandall Spanglerenum {
1731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	OPT_KLOADADDR = 1000,
1817f8d341099120da78a6ca71165834eefb0960edRandall Spangler};
1946186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry
207351ed7a3cf2759ac043d341d94f16e0ecd139f0Mike Frysingerstatic const struct option long_opts[] = {
2131d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	{"kloadaddr", 1, NULL, OPT_KLOADADDR},
2231d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	{NULL, 0, NULL, 0}
2317f8d341099120da78a6ca71165834eefb0960edRandall Spangler};
2446186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry
2517f8d341099120da78a6ca71165834eefb0960edRandall Spangler/* Print help and return error */
26779796f57e1e0236ea502248ede2cbea986fca21Bill Richardsonstatic void PrintHelp(const char *progname)
2731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson{
28779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson	printf("\nUsage:  " MYNAME " %s [--kloadaddr ADDRESS] "
29779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson	       "KERNEL_PARTITION\n\n", progname);
3017f8d341099120da78a6ca71165834eefb0960edRandall Spangler}
3146186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry
3231d95c2386df8d3d5ec619a077960645d052fa38Bill Richardsonstatic int do_dump_kernel_config(int argc, char *argv[])
3331d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson{
3431d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	char *infile = NULL;
3531d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	char *config = NULL;
3631d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	uint64_t kernel_body_load_address = USE_PREAMBLE_LOAD_ADDR;
3731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	int parse_error = 0;
3831d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	char *e;
3931d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	int i;
4031d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
4131d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) &&
4231d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	       !parse_error) {
4331d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		switch (i) {
4431d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		default:
4531d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		case '?':
4631d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			/* Unhandled option */
4731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			parse_error = 1;
4831d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			break;
4931d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
5031d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		case 0:
5131d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			/* silently handled option */
5231d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			break;
5331d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
5431d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		case OPT_KLOADADDR:
5531d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			kernel_body_load_address = strtoul(optarg, &e, 0);
5631d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			if (!*optarg || (e && *e)) {
5731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson				fprintf(stderr, "Invalid --kloadaddr\n");
5831d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson				parse_error = 1;
5931d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			}
6031d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson			break;
6131d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		}
6231d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	}
6331d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
6431d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	if (optind >= argc) {
6531d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		fprintf(stderr, "Expected argument after options\n");
6631d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		parse_error = 1;
6731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	} else
6831d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		infile = argv[optind];
6931d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
70779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson	if (parse_error) {
71779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson		PrintHelp(argv[0]);
72779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson		return 1;
73779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson	}
7431d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
7531d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	if (!infile || !*infile) {
7631d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		fprintf(stderr, "Must specify filename\n");
7731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		return 1;
7831d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	}
7931d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
8031d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	config = FindKernelConfig(infile, kernel_body_load_address);
8131d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	if (!config)
8231d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson		return 1;
8331d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
8431d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	printf("%s", config);
8531d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson
8631d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	free(config);
8731d95c2386df8d3d5ec619a077960645d052fa38Bill Richardson	return 0;
8846186faf4620c9775836bf8ad703fb6c481e68cdWill Drewry}
896f3961507e73f90cec665896dece884e86be560aBill Richardson
906f3961507e73f90cec665896dece884e86be560aBill RichardsonDECLARE_FUTIL_COMMAND(dump_kernel_config, do_dump_kernel_config,
911eae873b6194db25781233d7a4aaee6a34160eecBill Richardson		      VBOOT_VERSION_ALL,
92779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson		      "Prints the kernel command line",
93779796f57e1e0236ea502248ede2cbea986fca21Bill Richardson		      PrintHelp);
94