Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* ----------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *   Copyright 2012 Intel Corporation; author H. Peter Anvin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * ----------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * earlycpio.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Find a specific cpio member; must precede any compressed content.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * This is used to locate data items in the initramfs used by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * kernel itself during early boot (before the main initramfs is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * decompressed.)  It is the responsibility of the initramfs creator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * to ensure that these items are uncompressed at the head of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * blob.  Depending on the boot loader or package tool that may be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * separate file or part of the same file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/earlycpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) enum cpio_fields {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	C_MAGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	C_INO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	C_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	C_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	C_GID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	C_NLINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	C_MTIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	C_FILESIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	C_MAJ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	C_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	C_RMAJ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	C_RMIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	C_NAMESIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	C_CHKSUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	C_NFIELDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * cpio_data find_cpio_data - Search for files in an uncompressed cpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * @path:       The directory to search for, including a slash at the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * @data:       Pointer to the cpio archive or a header inside
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * @len:        Remaining length of the cpio based on data pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * @nextoff:    When a matching file is found, this is the offset from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *              beginning of the cpio to the beginning of the next file, not the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *              matching file itself. It can be used to iterate through the cpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *              to find all files inside of a directory path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * @return:     struct cpio_data containing the address, length and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *              filename (with the directory path cut off) of the found file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *              If you search for a filename and not for files in a directory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *              pass the absolute path of the filename in the cpio and make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *              the match returned an empty filename string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) struct cpio_data find_cpio_data(const char *path, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 				size_t len,  long *nextoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	const size_t cpio_header_len = 8*C_NFIELDS - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct cpio_data cd = { NULL, 0, "" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	const char *p, *dptr, *nptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	unsigned int ch[C_NFIELDS], *chp, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	unsigned char c, x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	size_t mypathsize = strlen(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	p = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	while (len > cpio_header_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		if (!*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			/* All cpio headers need to be 4-byte aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			p += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		j = 6;		/* The magic field is only 6 characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		chp = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		for (i = C_NFIELDS; i; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			while (j--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 				v <<= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				c = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 				x = c - '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				if (x < 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 					v += x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				x = (c | 0x20) - 'a';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 				if (x < 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 					v += x + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 				goto quit; /* Invalid hexadecimal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			*chp++ = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			j = 8;	/* All other fields are 8 characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		if ((ch[C_MAGIC] - 0x070701) > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			goto quit; /* Invalid magic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		len -= cpio_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		dptr = PTR_ALIGN(p + ch[C_NAMESIZE], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		nptr = PTR_ALIGN(dptr + ch[C_FILESIZE], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		if (nptr > p + len || dptr < p || nptr < dptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			goto quit; /* Buffer overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		if ((ch[C_MODE] & 0170000) == 0100000 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		    ch[C_NAMESIZE] >= mypathsize &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		    !memcmp(p, path, mypathsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			if (nextoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 				*nextoff = (long)nptr - (long)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			if (ch[C_NAMESIZE] - mypathsize >= MAX_CPIO_FILE_NAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 				pr_warn(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				"File %s exceeding MAX_CPIO_FILE_NAME [%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 				p, MAX_CPIO_FILE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			strlcpy(cd.name, p + mypathsize, MAX_CPIO_FILE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			cd.data = (void *)dptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			cd.size = ch[C_FILESIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			return cd; /* Found it! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		len -= (nptr - p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		p = nptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) quit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }