aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/functions.sh
blob: ec0618c2728881860354d52081c7bfc49be8ccfd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/bin/sh


get_magic_word() {
	dd if=$1 bs=4 count=1 2>/dev/null | od -A n -N 4 -t x1 | tr -d ' '
}

get_post_padding_word() {
	local rootfs_length="$(stat -c%s "$1")"
	[ "$rootfs_length" -ge 4 ] || return
	rootfs_length=$((rootfs_length-4))

	# the JFFS2 end marker must be on a 4K boundary (often 64K or 256K)
	local unaligned_bytes=$((rootfs_length%4096))
	[ "$unaligned_bytes" = 0 ] || return

	# skip rootfs data except the potential EOF marker
	dd if="$1" bs=1 skip="$rootfs_length" 2>/dev/null | od -A n -N 4 -t x1 | tr -d ' '
}

get_fs_type() {
	local magic_word="$(get_magic_word "$1")"

	case "$magic_word" in
	"3118"*)
		echo "ubifs"
		;;
	"68737173")
		local post_padding_word="$(get_post_padding_word "$1")"

		case "$post_padding_word" in
		"deadc0de")
			echo "squashfs-jffs2"
			;;
		*)
			echo "squashfs"
			;;
		esac
		;;
	*)
		echo "unknown"
		;;
	esac
}

round_up() {
	echo "$(((($1 + ($2 - 1))/ $2) * $2))"
}
t *)pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); + pgd_list_add(pgd); + spin_unlock_irqrestore(&pgd_lock, flags); + } } /* never called when PTRS_PER_PMD > 1 */ @@ -238,6 +239,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm) goto out_oom; set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); } + + if (!HAVE_SHARED_KERNEL_PMD) { + unsigned long flags; + + for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { + pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); + if (!pmd) + goto out_oom; + set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd))); + } + + spin_lock_irqsave(&pgd_lock, flags); + for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { + unsigned long v = (unsigned long)i << PGDIR_SHIFT; + pgd_t *kpgd = pgd_offset_k(v); + pud_t *kpud = pud_offset(kpgd, v); + pmd_t *kpmd = pmd_offset(kpud, v); + pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); + memcpy(pmd, kpmd, PAGE_SIZE); + } + pgd_list_add(pgd); + spin_unlock_irqrestore(&pgd_lock, flags); + } + return pgd; out_oom: @@ -252,9 +277,23 @@ void pgd_free(pgd_t *pgd) int i; /* in the PAE case user pgd entries are overwritten before usage */ - if (PTRS_PER_PMD > 1) - for (i = 0; i < USER_PTRS_PER_PGD; ++i) - kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + if (PTRS_PER_PMD > 1) { + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); + kmem_cache_free(pmd_cache, pmd); + } + if (!HAVE_SHARED_KERNEL_PMD) { + unsigned long flags; + spin_lock_irqsave(&pgd_lock, flags); + pgd_list_del(pgd); + spin_unlock_irqrestore(&pgd_lock, flags); + for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) { + pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1); + memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); + kmem_cache_free(pmd_cache, pmd); + } + } + } /* in the non-PAE case, free_pgtables() clears user pgd entries */ kmem_cache_free(pgd_cache, pgd); } diff -urNpP linux-2.6.12/include/asm-i386/pgtable-2level-defs.h linux-2.6.12.new/include/asm-i386/pgtable-2level-defs.h --- linux-2.6.12/include/asm-i386/pgtable-2level-defs.h 2005-06-17 20:48:29.000000000 +0100 +++ linux-2.6.12.new/include/asm-i386/pgtable-2level-defs.h 2005-07-11 16:28:09.733164251 +0100 @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_2LEVEL_DEFS_H #define _I386_PGTABLE_2LEVEL_DEFS_H +#define HAVE_SHARED_KERNEL_PMD 0 + /* * traditional i386 two-level paging structure: */ diff -urNpP linux-2.6.12/include/asm-i386/pgtable-3level-defs.h linux-2.6.12.new/include/asm-i386/pgtable-3level-defs.h --- linux-2.6.12/include/asm-i386/pgtable-3level-defs.h 2005-06-17 20:48:29.000000000 +0100 +++ linux-2.6.12.new/include/asm-i386/pgtable-3level-defs.h 2005-07-11 16:28:09.755164902 +0100 @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_3LEVEL_DEFS_H #define _I386_PGTABLE_3LEVEL_DEFS_H +#define HAVE_SHARED_KERNEL_PMD 1 + /* * PGDIR_SHIFT determines what a top-level page table entry can map */