Merge "Add "fastboot --version"."
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index c36313b..4e935e6 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -59,7 +59,6 @@
char cur_product[FB_RESPONSE_SZ + 1];
-static usb_handle *usb = 0;
static const char *serial = 0;
static const char *product = 0;
static const char *cmdline = 0;
@@ -619,7 +618,7 @@
* erase partitions of type ext4 before flashing a filesystem so no stale
* inodes are left lying around. Otherwise, e2fsck gets very upset.
*/
-static int needs_erase(const char *part)
+static int needs_erase(usb_handle* usb, const char *part)
{
/* The function fb_format_supported() currently returns the value
* we want, so just call it.
@@ -744,7 +743,7 @@
int rc = load_buf_fd(usb, fd, &buf);
if (rc) die("cannot load %s from flash", images[i].img_name);
do_update_signature(zip, images[i].sig_name);
- if (erase_first && needs_erase(images[i].part_name)) {
+ if (erase_first && needs_erase(usb, images[i].part_name)) {
fb_queue_erase(images[i].part_name);
}
flash_buf(images[i].part_name, &buf);
@@ -799,7 +798,7 @@
die("could not load %s\n", images[i].img_name);
}
do_send_signature(fname);
- if (erase_first && needs_erase(images[i].part_name)) {
+ if (erase_first && needs_erase(usb, images[i].part_name)) {
fb_queue_erase(images[i].part_name);
}
flash_buf(images[i].part_name, &buf);
@@ -867,7 +866,8 @@
return num;
}
-void fb_perform_format(const char *partition, int skip_if_not_supported,
+void fb_perform_format(usb_handle* usb,
+ const char *partition, int skip_if_not_supported,
const char *type_override, const char *size_override)
{
char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1];
@@ -1074,7 +1074,7 @@
return 0;
}
- usb = open_device();
+ usb_handle* usb = open_device();
while (argc > 0) {
if(!strcmp(*argv, "getvar")) {
@@ -1116,10 +1116,10 @@
}
if (type_override && !type_override[0]) type_override = NULL;
if (size_override && !size_override[0]) size_override = NULL;
- if (erase_first && needs_erase(argv[1])) {
+ if (erase_first && needs_erase(usb, argv[1])) {
fb_queue_erase(argv[1]);
}
- fb_perform_format(argv[1], 0, type_override, size_override);
+ fb_perform_format(usb, argv[1], 0, type_override, size_override);
skip(2);
} else if(!strcmp(*argv, "signature")) {
require(2);
@@ -1179,7 +1179,7 @@
skip(2);
}
if (fname == 0) die("cannot determine image filename for '%s'", pname);
- if (erase_first && needs_erase(pname)) {
+ if (erase_first && needs_erase(usb, pname)) {
fb_queue_erase(pname);
}
do_flash(usb, pname, fname);
@@ -1234,9 +1234,9 @@
if (wants_wipe) {
fb_queue_erase("userdata");
- fb_perform_format("userdata", 1, NULL, NULL);
+ fb_perform_format(usb, "userdata", 1, NULL, NULL);
fb_queue_erase("cache");
- fb_perform_format("cache", 1, NULL, NULL);
+ fb_perform_format(usb, "cache", 1, NULL, NULL);
}
if (wants_reboot) {
fb_queue_reboot();
diff --git a/init/init.cpp b/init/init.cpp
index 60fcf64..2500985 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -380,7 +380,8 @@
if ((svc->flags & SVC_EXEC) != 0) {
INFO("SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...\n",
- svc->pid, svc->uid, svc->gid, svc->nr_supp_gids, svc->seclabel);
+ svc->pid, svc->uid, svc->gid, svc->nr_supp_gids,
+ svc->seclabel ? : "default");
waiting_for_exec = true;
}
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index df049ed..f975b6c 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -664,6 +664,7 @@
service* make_exec_oneshot_service(int nargs, char** args) {
// Parse the arguments: exec [SECLABEL [UID [GID]*] --] COMMAND ARGS...
+ // SECLABEL can be a - to denote default
int command_arg = 1;
for (int i = 1; i < nargs; ++i) {
if (strcmp(args[i], "--") == 0) {
@@ -689,7 +690,7 @@
return NULL;
}
- if (command_arg > 2) {
+ if ((command_arg > 2) && strcmp(args[1], "-")) {
svc->seclabel = args[1];
}
if (command_arg > 3) {
diff --git a/init/readme.txt b/init/readme.txt
index 6b9c42d..c213041 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -180,7 +180,7 @@
Fork and execute command with the given arguments. The command starts
after "--" so that an optional security context, user, and supplementary
groups can be provided. No other commands will be run until this one
- finishes.
+ finishes. <seclabel> can be a - to denote default.
export <name> <value>
Set the environment variable <name> equal to <value> in the
diff --git a/liblog/log_time.cpp b/liblog/log_time.cpp
index 50742df..9d5ea0e 100644
--- a/liblog/log_time.cpp
+++ b/liblog/log_time.cpp
@@ -22,7 +22,7 @@
#include <log/log_read.h>
-const char log_time::default_format[] = "%m-%d %H:%M:%S.%3q";
+const char log_time::default_format[] = "%m-%d %H:%M:%S.%q";
const timespec log_time::EPOCH = { 0, 0 };
// Add %#q for fractional seconds to standard strptime function
diff --git a/logcat/Android.mk b/logcat/Android.mk
index f46a4de..7115f9b 100644
--- a/logcat/Android.mk
+++ b/logcat/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES:= logcat.cpp event.logtags
-LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES := liblog libbase libcutils
LOCAL_MODULE := logcat
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 2c2d785..6d7740e 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -1,29 +1,38 @@
// Copyright 2006-2015 The Android Open Source Project
+#include <arpa/inet.h>
#include <assert.h>
#include <ctype.h>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdarg.h>
#include <string.h>
-#include <signal.h>
-#include <time.h>
-#include <unistd.h>
#include <sys/cdefs.h>
#include <sys/socket.h>
#include <sys/stat.h>
-#include <arpa/inet.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <memory>
+#include <string>
+
+#include <base/file.h>
+#include <base/strings.h>
+#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
+#include <log/event_tag_map.h>
#include <log/log.h>
#include <log/log_read.h>
-#include <log/logger.h>
#include <log/logd.h>
+#include <log/logger.h>
#include <log/logprint.h>
-#include <log/event_tag_map.h>
#define DEFAULT_MAX_ROTATED_LOGS 4
@@ -202,7 +211,15 @@
g_outFD = STDOUT_FILENO;
} else {
- struct stat statbuf;
+ if (set_sched_policy(0, SP_BACKGROUND) < 0) {
+ fprintf(stderr, "failed to set background scheduling policy\n");
+ }
+
+ struct sched_param param;
+ memset(¶m, 0, sizeof(param));
+ if (sched_setscheduler((pid_t) 0, SCHED_BATCH, ¶m) < 0) {
+ fprintf(stderr, "failed to set to batch scheduler\n");
+ }
g_outFD = openLogFile (g_outputFileName);
@@ -210,6 +227,7 @@
logcat_panic(false, "couldn't open output file");
}
+ struct stat statbuf;
if (fstat(g_outFD, &statbuf) == -1) {
close(g_outFD);
logcat_panic(false, "couldn't get output file stat\n");
@@ -231,7 +249,7 @@
fprintf(stderr, "options include:\n"
" -s Set default filter to silent.\n"
" Like specifying filterspec '*:S'\n"
- " -f <filename> Log to file. Default to stdout\n"
+ " -f <filename> Log to file. Default is stdout\n"
" -r <kbytes> Rotate log every kbytes. Requires -f\n"
" -n <count> Sets max number of rotated logs to <count>, default 4\n"
" -v <format> Sets the log print format, where <format> is:\n\n"
@@ -352,6 +370,86 @@
exit(EXIT_FAILURE);
}
+static const char g_defaultTimeFormat[] = "%m-%d %H:%M:%S.%q";
+
+// Find last logged line in gestalt of all matching existing output files
+static log_time lastLogTime(char *outputFileName) {
+ log_time retval(log_time::EPOCH);
+ if (!outputFileName) {
+ return retval;
+ }
+
+ log_time now(CLOCK_REALTIME);
+
+ std::string directory;
+ char *file = strrchr(outputFileName, '/');
+ if (!file) {
+ directory = ".";
+ file = outputFileName;
+ } else {
+ *file = '\0';
+ directory = outputFileName;
+ *file = '/';
+ ++file;
+ }
+ size_t len = strlen(file);
+ log_time modulo(0, NS_PER_SEC);
+ std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(directory.c_str()), closedir);
+ struct dirent *dp;
+ while ((dp = readdir(dir.get())) != NULL) {
+ if ((dp->d_type != DT_REG)
+ || strncmp(dp->d_name, file, len)
+ || (dp->d_name[len]
+ && ((dp->d_name[len] != '.')
+ || !isdigit(dp->d_name[len+1])))) {
+ continue;
+ }
+
+ std::string file_name = directory;
+ file_name += "/";
+ file_name += dp->d_name;
+ std::string file;
+ if (!android::base::ReadFileToString(file_name, &file)) {
+ continue;
+ }
+
+ bool found = false;
+ for (const auto& line : android::base::Split(file, "\n")) {
+ log_time t(log_time::EPOCH);
+ char *ep = t.strptime(line.c_str(), g_defaultTimeFormat);
+ if (!ep || (*ep != ' ')) {
+ continue;
+ }
+ // determine the time precision of the logs (eg: msec or usec)
+ for (unsigned long mod = 1UL; mod < modulo.tv_nsec; mod *= 10) {
+ if (t.tv_nsec % (mod * 10)) {
+ modulo.tv_nsec = mod;
+ break;
+ }
+ }
+ // We filter any times later than current as we may not have the
+ // year stored with each log entry. Also, since it is possible for
+ // entries to be recorded out of order (very rare) we select the
+ // maximum we find just in case.
+ if ((t < now) && (t > retval)) {
+ retval = t;
+ found = true;
+ }
+ }
+ // We count on the basename file to be the definitive end, so stop here.
+ if (!dp->d_name[len] && found) {
+ break;
+ }
+ }
+ if (retval == log_time::EPOCH) {
+ return retval;
+ }
+ // tail_time prints matching or higher, round up by the modulo to prevent
+ // a replay of the last entry we have just checked.
+ retval += modulo;
+ return retval;
+}
+
} /* namespace android */
@@ -417,12 +515,11 @@
/* FALLTHRU */
case 'T':
if (strspn(optarg, "0123456789") != strlen(optarg)) {
- char *cp = tail_time.strptime(optarg,
- log_time::default_format);
+ char *cp = tail_time.strptime(optarg, g_defaultTimeFormat);
if (!cp) {
logcat_panic(false,
"-%c \"%s\" not in \"%s\" time format\n",
- ret, optarg, log_time::default_format);
+ ret, optarg, g_defaultTimeFormat);
}
if (*cp) {
char c = *cp;
@@ -545,9 +642,11 @@
break;
case 'f':
+ if ((tail_time == log_time::EPOCH) && (tail_lines != 0)) {
+ tail_time = lastLogTime(optarg);
+ }
// redirect output to a file
g_outputFileName = optarg;
-
break;
case 'r':
diff --git a/logd/Android.mk b/logd/Android.mk
index 73da8dc..615d030 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -41,4 +41,15 @@
include $(BUILD_EXECUTABLE)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := logpersist.start
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_PATH := $(bin_dir)
+LOCAL_SRC_FILES := logpersist
+ALL_TOOLS := logpersist.start logpersist.stop logpersist.cat
+LOCAL_POST_INSTALL_CMD := $(hide) $(foreach t,$(filter-out $(LOCAL_MODULE),$(ALL_TOOLS)),ln -sf $(LOCAL_MODULE) $(TARGET_OUT)/bin/$(t);)
+include $(BUILD_PREBUILT)
+
include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/logd/README.property b/logd/README.property
index ad7d0cd..a472efd 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -10,6 +10,8 @@
default false
ro.build.type string if user, logd.statistics & logd.klogd
default false
+persist.logd.logpersistd string Enable logpersist daemon, "logcatd"
+ turns on logcat -f in logd context
persist.logd.size number 256K default size of the buffer for all
log ids at initial startup, at runtime
use: logcat -b all -G <value>
diff --git a/logd/logpersist b/logd/logpersist
new file mode 100755
index 0000000..215e1e2
--- /dev/null
+++ b/logd/logpersist
@@ -0,0 +1,36 @@
+#! /system/bin/sh
+# logpersist cat start and stop handlers
+data=/data/misc/logd
+property=persist.logd.logpersistd
+service=logcatd
+progname="${0##*/}"
+if [ X"${1}" = "-h" -o X"${1}" = X"--help" ]; then
+ echo "${progname%.*}.cat - dump current ${service%d} logs"
+ echo "${progname%.*}.start - start ${service} service"
+ echo "${progname%.*}.stop [--clear] - stop ${service} service"
+ exit 0
+fi
+case ${progname} in
+*.cat)
+ su 1036 ls "${data}" |
+ tr -d '\r' |
+ sort -ru |
+ sed "s#^#${data}/#" |
+ su 1036 xargs cat
+ ;;
+*.start)
+ su 0 setprop ${property} ${service}
+ getprop ${property}
+ sleep 1
+ ps -t | grep "${data##*/}.*${service%d}"
+ ;;
+*.stop)
+ su 0 stop ${service}
+ su 0 setprop ${property} ""
+ [ X"${1}" != X"-c" -a X"${1}" != X"--clear" ] ||
+ ( sleep 1 ; su 1036,9998 rm -rf "${data}" )
+ ;;
+*)
+ echo "Unexpected command ${0##*/} ${@}" >&2
+ exit 1
+esac
diff --git a/mkbootimg/Android.mk b/mkbootimg/Android.mk
index 0c9b0c6..8661d7d 100644
--- a/mkbootimg/Android.mk
+++ b/mkbootimg/Android.mk
@@ -2,12 +2,10 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := mkbootimg.c
-LOCAL_STATIC_LIBRARIES := libmincrypt
-LOCAL_CFLAGS := -Werror
+LOCAL_SRC_FILES := mkbootimg
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_IS_HOST_MODULE := true
LOCAL_MODULE := mkbootimg
-include $(BUILD_HOST_EXECUTABLE)
-
-$(call dist-for-goals,dist_files,$(LOCAL_BUILT_MODULE))
+include $(BUILD_PREBUILT)
diff --git a/mkbootimg/mkbootimg b/mkbootimg/mkbootimg
new file mode 100755
index 0000000..1e09f4d
--- /dev/null
+++ b/mkbootimg/mkbootimg
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# Copyright 2015, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+from sys import argv, exit, stderr
+from argparse import ArgumentParser, FileType, Action
+from os import fstat
+from struct import pack
+from hashlib import sha1
+
+def filesize(f):
+ if f is None:
+ return 0
+ try:
+ return fstat(f.fileno()).st_size
+ except OSError:
+ return 0
+
+
+def update_sha(sha, f):
+ if f:
+ sha.update(f.read())
+ f.seek(0)
+ sha.update(pack('I', filesize(f)))
+ else:
+ sha.update(pack('I', 0))
+
+
+def pad_file(f, padding):
+ pad = (padding - (f.tell() & (padding - 1))) & (padding - 1)
+ f.write(pack(str(pad) + 'x'))
+
+
+def write_header(args):
+ BOOT_MAGIC = 'ANDROID!'.encode()
+ args.output.write(pack('8s', BOOT_MAGIC))
+ args.output.write(pack('8I',
+ filesize(args.kernel), # size in bytes
+ args.base + args.kernel_offset, # physical load addr
+ filesize(args.ramdisk), # size in bytes
+ args.base + args.ramdisk_offset, # physical load addr
+ filesize(args.second), # size in bytes
+ args.base + args.second_offset, # physical load addr
+ args.base + args.tags_offset, # physical addr for kernel tags
+ args.pagesize)) # flash page size we assume
+ args.output.write(pack('8x')) # future expansion: should be 0
+ args.output.write(pack('16s', args.board.encode())) # asciiz product name
+ args.output.write(pack('512s', args.cmdline[:512].encode()))
+
+ sha = sha1()
+ update_sha(sha, args.kernel)
+ update_sha(sha, args.ramdisk)
+ update_sha(sha, args.second)
+ img_id = pack('32s', sha.digest())
+
+ args.output.write(img_id)
+ args.output.write(pack('1024s', args.cmdline[512:].encode()))
+ pad_file(args.output, args.pagesize)
+ return img_id
+
+
+class ValidateStrLenAction(Action):
+ def __init__(self, option_strings, dest, nargs=None, **kwargs):
+ if 'maxlen' not in kwargs:
+ raise ValueError('maxlen must be set')
+ self.maxlen = int(kwargs['maxlen'])
+ del kwargs['maxlen']
+ super(ValidateStrLenAction, self).__init__(option_strings, dest, **kwargs)
+
+ def __call__(self, parser, namespace, values, option_string=None):
+ if len(values) > self.maxlen:
+ raise ValueError('String argument too long: max {0:d}, got {1:d}'.
+ format(self.maxlen, len(values)))
+ setattr(namespace, self.dest, values)
+
+
+def write_padded_file(f_out, f_in, padding):
+ if f_in is None:
+ return
+ f_out.write(f_in.read())
+ pad_file(f_out, padding)
+
+
+def parse_int(x):
+ return int(x,0)
+
+
+def parse_cmdline():
+ parser = ArgumentParser()
+ parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'),
+ required=True)
+ parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))
+ parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))
+ parser.add_argument('--cmdline', help='extra arguments to be passed on the '
+ 'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)
+ parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)
+ parser.add_argument('----kernel_offset', help='kernel offset', type=parse_int, default=0x00008000)
+ parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int, default=0x01000000)
+ parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,
+ default=0x00f00000)
+ parser.add_argument('--tags_offset', help='tags offset', type=parse_int, default=0x00000100)
+ parser.add_argument('--board', help='board name', default='', action=ValidateStrLenAction,
+ maxlen=16)
+ parser.add_argument('--pagesize', help='page size', type=parse_int,
+ choices=[2**i for i in range(11,15)], default=2048)
+ parser.add_argument('--id', help='print the image ID on standard output',
+ action='store_true')
+ parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'),
+ required=True)
+ return parser.parse_args()
+
+
+def write_data(args):
+ write_padded_file(args.output, args.kernel, args.pagesize)
+ write_padded_file(args.output, args.ramdisk, args.pagesize)
+ write_padded_file(args.output, args.second, args.pagesize)
+
+
+def main():
+ args = parse_cmdline()
+ img_id = write_header(args)
+ write_data(args)
+ if args.id:
+ print('0x' + ''.join('{:02x}'.format(ord(c)) for c in img_id))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
deleted file mode 100644
index 40e5261..0000000
--- a/mkbootimg/mkbootimg.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/* tools/mkbootimg/mkbootimg.c
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdbool.h>
-
-#include "mincrypt/sha.h"
-#include "bootimg.h"
-
-static void *load_file(const char *fn, unsigned *_sz)
-{
- char *data;
- int sz;
- int fd;
-
- data = 0;
- fd = open(fn, O_RDONLY);
- if(fd < 0) return 0;
-
- sz = lseek(fd, 0, SEEK_END);
- if(sz < 0) goto oops;
-
- if(lseek(fd, 0, SEEK_SET) != 0) goto oops;
-
- data = (char*) malloc(sz);
- if(data == 0) goto oops;
-
- if(read(fd, data, sz) != sz) goto oops;
- close(fd);
-
- if(_sz) *_sz = sz;
- return data;
-
-oops:
- close(fd);
- if(data != 0) free(data);
- return 0;
-}
-
-int usage(void)
-{
- fprintf(stderr,"usage: mkbootimg\n"
- " --kernel <filename>\n"
- " --ramdisk <filename>\n"
- " [ --second <2ndbootloader-filename> ]\n"
- " [ --cmdline <kernel-commandline> ]\n"
- " [ --board <boardname> ]\n"
- " [ --base <address> ]\n"
- " [ --pagesize <pagesize> ]\n"
- " [ --id ]\n"
- " -o|--output <filename>\n"
- );
- return 1;
-}
-
-
-
-static unsigned char padding[16384] = { 0, };
-
-static void print_id(const uint8_t *id, size_t id_len) {
- printf("0x");
- for (unsigned i = 0; i < id_len; i++) {
- printf("%02x", id[i]);
- }
- printf("\n");
-}
-
-int write_padding(int fd, unsigned pagesize, unsigned itemsize)
-{
- unsigned pagemask = pagesize - 1;
- ssize_t count;
-
- if((itemsize & pagemask) == 0) {
- return 0;
- }
-
- count = pagesize - (itemsize & pagemask);
-
- if(write(fd, padding, count) != count) {
- return -1;
- } else {
- return 0;
- }
-}
-
-int main(int argc, char **argv)
-{
- boot_img_hdr hdr;
-
- char *kernel_fn = NULL;
- void *kernel_data = NULL;
- char *ramdisk_fn = NULL;
- void *ramdisk_data = NULL;
- char *second_fn = NULL;
- void *second_data = NULL;
- char *cmdline = "";
- char *bootimg = NULL;
- char *board = "";
- uint32_t pagesize = 2048;
- int fd;
- SHA_CTX ctx;
- const uint8_t* sha;
- uint32_t base = 0x10000000U;
- uint32_t kernel_offset = 0x00008000U;
- uint32_t ramdisk_offset = 0x01000000U;
- uint32_t second_offset = 0x00f00000U;
- uint32_t tags_offset = 0x00000100U;
- size_t cmdlen;
-
- argc--;
- argv++;
-
- memset(&hdr, 0, sizeof(hdr));
-
- bool get_id = false;
- while(argc > 0){
- char *arg = argv[0];
- if (!strcmp(arg, "--id")) {
- get_id = true;
- argc -= 1;
- argv += 1;
- } else if(argc >= 2) {
- char *val = argv[1];
- argc -= 2;
- argv += 2;
- if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
- bootimg = val;
- } else if(!strcmp(arg, "--kernel")) {
- kernel_fn = val;
- } else if(!strcmp(arg, "--ramdisk")) {
- ramdisk_fn = val;
- } else if(!strcmp(arg, "--second")) {
- second_fn = val;
- } else if(!strcmp(arg, "--cmdline")) {
- cmdline = val;
- } else if(!strcmp(arg, "--base")) {
- base = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--kernel_offset")) {
- kernel_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--ramdisk_offset")) {
- ramdisk_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--second_offset")) {
- second_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--tags_offset")) {
- tags_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--board")) {
- board = val;
- } else if(!strcmp(arg,"--pagesize")) {
- pagesize = strtoul(val, 0, 10);
- if ((pagesize != 2048) && (pagesize != 4096)
- && (pagesize != 8192) && (pagesize != 16384)) {
- fprintf(stderr,"error: unsupported page size %d\n", pagesize);
- return -1;
- }
- } else {
- return usage();
- }
- } else {
- return usage();
- }
- }
- hdr.page_size = pagesize;
-
- hdr.kernel_addr = base + kernel_offset;
- hdr.ramdisk_addr = base + ramdisk_offset;
- hdr.second_addr = base + second_offset;
- hdr.tags_addr = base + tags_offset;
-
- if(bootimg == 0) {
- fprintf(stderr,"error: no output filename specified\n");
- return usage();
- }
-
- if(kernel_fn == 0) {
- fprintf(stderr,"error: no kernel image specified\n");
- return usage();
- }
-
- if(ramdisk_fn == 0) {
- fprintf(stderr,"error: no ramdisk image specified\n");
- return usage();
- }
-
- if(strlen(board) >= BOOT_NAME_SIZE) {
- fprintf(stderr,"error: board name too large\n");
- return usage();
- }
-
- strcpy((char *) hdr.name, board);
-
- memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);
-
- cmdlen = strlen(cmdline);
- if(cmdlen > (BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - 2)) {
- fprintf(stderr,"error: kernel commandline too large\n");
- return 1;
- }
- /* Even if we need to use the supplemental field, ensure we
- * are still NULL-terminated */
- strncpy((char *)hdr.cmdline, cmdline, BOOT_ARGS_SIZE - 1);
- hdr.cmdline[BOOT_ARGS_SIZE - 1] = '\0';
- if (cmdlen >= (BOOT_ARGS_SIZE - 1)) {
- cmdline += (BOOT_ARGS_SIZE - 1);
- strncpy((char *)hdr.extra_cmdline, cmdline, BOOT_EXTRA_ARGS_SIZE);
- }
-
- kernel_data = load_file(kernel_fn, &hdr.kernel_size);
- if(kernel_data == 0) {
- fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn);
- return 1;
- }
-
- if(!strcmp(ramdisk_fn,"NONE")) {
- ramdisk_data = 0;
- hdr.ramdisk_size = 0;
- } else {
- ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size);
- if(ramdisk_data == 0) {
- fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn);
- return 1;
- }
- }
-
- if(second_fn) {
- second_data = load_file(second_fn, &hdr.second_size);
- if(second_data == 0) {
- fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn);
- return 1;
- }
- }
-
- /* put a hash of the contents in the header so boot images can be
- * differentiated based on their first 2k.
- */
- SHA_init(&ctx);
- SHA_update(&ctx, kernel_data, hdr.kernel_size);
- SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size));
- SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size);
- SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size));
- SHA_update(&ctx, second_data, hdr.second_size);
- SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size));
- sha = SHA_final(&ctx);
- memcpy(hdr.id, sha,
- SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE);
-
- fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644);
- if(fd < 0) {
- fprintf(stderr,"error: could not create '%s'\n", bootimg);
- return 1;
- }
-
- if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail;
- if(write_padding(fd, pagesize, sizeof(hdr))) goto fail;
-
- if(write(fd, kernel_data, hdr.kernel_size) != (ssize_t) hdr.kernel_size) goto fail;
- if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail;
-
- if(write(fd, ramdisk_data, hdr.ramdisk_size) != (ssize_t) hdr.ramdisk_size) goto fail;
- if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;
-
- if(second_data) {
- if(write(fd, second_data, hdr.second_size) != (ssize_t) hdr.second_size) goto fail;
- if(write_padding(fd, pagesize, hdr.second_size)) goto fail;
- }
-
- if (get_id) {
- print_id((uint8_t *) hdr.id, sizeof(hdr.id));
- }
-
- return 0;
-
-fail:
- unlink(bootimg);
- close(fd);
- fprintf(stderr,"error: failed writing '%s': %s\n", bootimg,
- strerror(errno));
- return 1;
-}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 0966038..1f421c5 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -649,3 +649,17 @@
class late_start
user root
oneshot
+
+on property:persist.logd.logpersistd=logcatd
+ # all exec/services are called with umask(077), so no gain beyond 0700
+ mkdir /data/misc/logd 0700 logd log
+ # logd for write to /data/misc/logd, log group for read from pstore (-L)
+ exec - logd log -- /system/bin/logcat -L -b all -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 64 -n 256
+ start logcatd
+
+service logcatd /system/bin/logcat -b all -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 64 -n 256
+ class late_start
+ disabled
+ # logd for write to /data/misc/logd, log group for read from log daemon
+ user logd
+ group log
diff --git a/rootdir/init.trace.rc b/rootdir/init.trace.rc
index cd8d350..50944e6 100644
--- a/rootdir/init.trace.rc
+++ b/rootdir/init.trace.rc
@@ -1,6 +1,6 @@
## Permissions to allow system-wide tracing to the kernel trace buffer.
##
-on early-boot
+on boot
# Allow writing to the kernel trace log.
chmod 0222 /sys/kernel/debug/tracing/trace_marker