From 9e80f07f7816f53abfe4533236ebb1f4c55eaf03 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Thu, 10 Sep 2026 15:45:04 +0300 Subject: [PATCH 1/6] gk7205v200: capture a crash log across reboot with pstore/ramoops A camera that boots but whose kernel panics or oopses (a driver/sensor init loop, a crashing streamer) leaves nothing behind: the console is muted, syslog is a RAM ring, and the panic=20 reboot wipes it. Enable pstore/ramoops so the last kernel log survives the warm reboot and is readable at /sys/fs/pstore on the next boot -- via kmsg_dump, which is independent of the muted console, so it works on these boards. (A cold power cut still loses it; that case is the bootloader firmware_scan recovery, not this.) 128 KiB is enough for one 64 KiB panic dump plus headroom (record_size 64K, mem_size 128K, console/pmsg zones off). The region is carved so it collides with neither Linux RAM nor the media (mmz) pool, in both goke allocators: gk (mem=osmem, mmz above): shrink the OS window by 128K and place ramoops in the freed gap [base+osmem-128K, base+osmem), just below mmz_start, which is unchanged -- the mmz pool is untouched. cma (mem=totalmem, mmz a CMA region inside it): reserve the top 1 MiB (mmz is M-granular there; a >=128 MiB cma board loses 1 MiB, negligible), drop mem= by the same 1 MiB, and place ramoops at the top, above both the kernel window and the media zone. set_allocator writes the ramoops.* params (and the reduced mem=) into bootargs; load_goke's check_allocator backfills them on a camera whose bootargs predate pstore (set_allocator otherwise only runs when mmz_allocator is absent), so the region reaches already-provisioned cameras on their next boot too. Effective on the boot after the rewrite, like every other set_allocator change. Scoped to gk7205v200 (its own osdrv package). Shell-parse and strip-comment gates pass; address math verified for both allocators. On-camera panic -> pstore verification under each allocator follows. --- .../gk7205v200/gk7205v200.generic.config | 8 +++- .../files/script/load_goke | 11 ++++++ .../files/script/set_allocator | 39 ++++++++++++++++--- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config b/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config index 2ae0c1f114..6fd2fd3382 100644 --- a/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config +++ b/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config @@ -2391,7 +2391,13 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=1 # CONFIG_QNX4FS_FS is not set # CONFIG_QNX6FS_FS is not set # CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set +CONFIG_PSTORE=y +# CONFIG_PSTORE_DEFLATE_COMPRESS is not set +# CONFIG_PSTORE_LZO_COMPRESS is not set +# CONFIG_PSTORE_LZ4_COMPRESS is not set +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_PMSG=y +CONFIG_PSTORE_RAM=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y diff --git a/general/package/goke-osdrv-gk7205v200/files/script/load_goke b/general/package/goke-osdrv-gk7205v200/files/script/load_goke index ed8b69067d..1d229a8e24 100755 --- a/general/package/goke-osdrv-gk7205v200/files/script/load_goke +++ b/general/package/goke-osdrv-gk7205v200/files/script/load_goke @@ -106,6 +106,17 @@ check_allocator() { else set_allocator gk fi + elif ! grep -q "ramoops.mem_address" /proc/cmdline; then + # Backfill the pstore ramoops region on a camera whose bootargs were + # written before pstore existed: set_allocator otherwise only runs when + # mmz_allocator is absent, so these cameras would never get it. The + # rewrite persists and takes effect on the next reboot (no forced reboot + # here); it converges in one cycle and then stops, because both branches + # below now add the token. Match the allocator already in use. + case "${allocator}" in + *mmz_allocator=cma*) set_allocator cma ;; + *mmz_allocator=gk*) set_allocator gk ;; + esac fi } diff --git a/general/package/goke-osdrv-gk7205v200/files/script/set_allocator b/general/package/goke-osdrv-gk7205v200/files/script/set_allocator index 50231ce523..fd6b18b7fb 100755 --- a/general/package/goke-osdrv-gk7205v200/files/script/set_allocator +++ b/general/package/goke-osdrv-gk7205v200/files/script/set_allocator @@ -1,5 +1,13 @@ #!/bin/sh +# 128K pstore/ramoops crash-log region: one 64K panic dump + headroom. +# Console zone 0 (the console is muted on these boards) -- rely on the +# oops/panic kmsg_dump, which is console-independent. +RAMOOPS_SIZE=0x20000 +ramoops_args() { # $1 = physical base address + echo "ramoops.mem_address=$1 ramoops.mem_size=${RAMOOPS_SIZE} ramoops.record_size=0x10000 ramoops.console_size=0 ramoops.pmsg_size=0 ramoops.dump_oops=1" +} + get_env() { bootargs=$(fw_printenv -n bootargs) @@ -22,16 +30,36 @@ calc_mmz() { os_mem_size=$(fw_printenv -n osmem | tr -d 'M') os_mem_size=${os_mem_size:=32} mmz_start=$(echo "$mem_start $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1/1024/1024 + $2; } END { printf("0x%x00000\n", temp); }') - mmz_size=$(echo "$mem_total $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1 - $2; } END { printf("%dM\n", temp); }') + # Reserve the top 1M of DRAM for ramoops (see below), so the media zone stops + # 1M short of the end. mmz is M-granular here, so reserving a whole M keeps it + # aligned; a cma board has >=128M, so the loss is negligible. + mmz_size=$(echo "$mem_total $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1 - $2 - 1; } END { printf("%dM\n", temp); }') mmz=anonymous,0,$mmz_start,$mmz_size + # ramoops lives in that reserved top megabyte, above both the (reduced) kernel + # window and the media zone. cma_mem is the OS size with the same 1M removed, + # so the kernel never maps the ramoops region. + cma_ramoops_addr=$(printf '0x%08x' $((0x40000000 + (mem_total - 1) * 1024 * 1024))) + cma_mem="$((mem_total - 1))M" } if [[ "$1" == 'gk' ]]; then echo "Allocator selected as gk..." get_env - mem=${osmem:=32M} - newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=gk ${extras}" + osmem=${osmem:=32M} + # Carve 128K off the TOP of the OS window for a ramoops crash-log region + # (pstore). It lands above the shrunk kernel window and below mmz_start + # (= base + osmem, unchanged), so it touches neither Linux RAM nor the media + # (mmz) pool -- the kernel never maps it and the gk allocator never sees it. + # kmsg_dump writes here on a panic/oops, so a crash survives the panic=20 + # reboot even though the console is muted. mem_address MUST equal + # base(0x40000000) + (osmem - 128K). + osk=$(echo "$osmem" | awk '{ gsub(/[Mm]/,""); printf "%d", $1 * 1024 }') + memk=$((osk - 128)) + raddr=$(printf '0x%08x' $((0x40000000 + memk * 1024))) + mem="${memk}K" + ramoops=$(ramoops_args "${raddr}") + newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=gk ${ramoops} ${extras}" echo ${newbootargs} fw_setenv bootargs ${newbootargs} # @@ -39,8 +67,9 @@ elif [[ "$1" == 'cma' ]]; then echo "Allocator selected as cma..." get_env calc_mmz - mem=${totalmem:=64M} - newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=cma mmz=${mmz} ${extras}" + mem=${cma_mem:=${totalmem:=64M}} + ramoops=$(ramoops_args "${cma_ramoops_addr}") + newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=cma mmz=${mmz} ${ramoops} ${extras}" fw_setenv bootargs ${newbootargs} echo ${newbootargs} else From 3d0f5a7d8177cd33c53f8f0cdef0dc68ac49c187 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Thu, 10 Sep 2026 16:02:24 +0300 Subject: [PATCH 2/6] gk7205v200: mount pstore, and stop rewriting provisioned cameras' bootargs (review) Two fixes from review of the pstore change: - Nothing mounted the pstore filesystem, so a crash log ramoops captured across the reboot was held in the reserved RAM but never exposed at /sys/fs/pstore. Add S29pstore, which mounts it when the kernel has pstore (inert otherwise), the same shape as S29debugfs. (finding: crash logs stay hidden after reboot) - check_allocator backfilled the ramoops bootargs on already-provisioned cameras by re-running set_allocator, but set_allocator rebuilds bootargs from a fixed set of parsed fields plus ${extras}, so any other custom kernel parameter stored directly in bootargs would be dropped on the next boot. Revert the backfill: ramoops is now added only through set_allocator's existing trigger (when mmz_allocator is absent -- a fresh env / firstboot), so a provisioned camera's bootargs are never rewritten. Fleet reach for existing cameras is deferred rather than bought at the cost of clobbering their kernel command line. (finding: upgrades erase custom boot options) --- general/overlay/etc/init.d/S29pstore | 21 +++++++++++++++++++ .../files/script/load_goke | 11 ---------- 2 files changed, 21 insertions(+), 11 deletions(-) create mode 100755 general/overlay/etc/init.d/S29pstore diff --git a/general/overlay/etc/init.d/S29pstore b/general/overlay/etc/init.d/S29pstore new file mode 100755 index 0000000000..3e53fb9af4 --- /dev/null +++ b/general/overlay/etc/init.d/S29pstore @@ -0,0 +1,21 @@ +#!/bin/sh +# Mount the pstore filesystem so a kernel crash log that ramoops captured across +# the reboot (a panic/oops, via kmsg_dump -- independent of the muted console) +# is readable at /sys/fs/pstore. Without this the records are held in the +# reserved RAM region but never exposed. Inert on a kernel built without pstore. +# The backing RAM region is set up in the goke set_allocator (ramoops.* bootargs). +case "$1" in + start) + if grep -q pstore /proc/filesystems; then + mkdir -p /sys/fs/pstore + mountpoint -q /sys/fs/pstore 2>/dev/null || + mount -t pstore pstore /sys/fs/pstore + fi + ;; + stop) + ;; + *) + echo "Usage: $0 {start|stop}" + exit 1 + ;; +esac diff --git a/general/package/goke-osdrv-gk7205v200/files/script/load_goke b/general/package/goke-osdrv-gk7205v200/files/script/load_goke index 1d229a8e24..ed8b69067d 100755 --- a/general/package/goke-osdrv-gk7205v200/files/script/load_goke +++ b/general/package/goke-osdrv-gk7205v200/files/script/load_goke @@ -106,17 +106,6 @@ check_allocator() { else set_allocator gk fi - elif ! grep -q "ramoops.mem_address" /proc/cmdline; then - # Backfill the pstore ramoops region on a camera whose bootargs were - # written before pstore existed: set_allocator otherwise only runs when - # mmz_allocator is absent, so these cameras would never get it. The - # rewrite persists and takes effect on the next reboot (no forced reboot - # here); it converges in one cycle and then stops, because both branches - # below now add the token. Match the allocator already in use. - case "${allocator}" in - *mmz_allocator=cma*) set_allocator cma ;; - *mmz_allocator=gk*) set_allocator gk ;; - esac fi } From 33c654ad450252a52cc49a807ec01ef40eb275bb Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Thu, 10 Sep 2026 16:13:52 +0300 Subject: [PATCH 3/6] gk7205v200: name pstore's real compressor symbol for this 4.9 kernel The disable line targeted CONFIG_PSTORE_DEFLATE_COMPRESS, a symbol this 4.9 kernel does not have (it was renamed from ZLIB in a later kernel), so it was a no-op. The compressor here is a mandatory Kconfig choice with no "none" arm; it defaults to ZLIB, whose workspace is preallocated at pstore_register so it is safe to compress from inside a panic. Name that symbol explicitly instead of a dead one. Resolved kernel config is unchanged (ZLIB was already selected). --- br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config b/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config index 6fd2fd3382..8b92bddcef 100644 --- a/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config +++ b/br-ext-chip-goke/board/gk7205v200/gk7205v200.generic.config @@ -2392,7 +2392,10 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=1 # CONFIG_QNX6FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_PSTORE=y -# CONFIG_PSTORE_DEFLATE_COMPRESS is not set +# Compression is a mandatory choice on this 4.9 kernel (it has no "none"); ZLIB +# is its default and the only one whose workspace is preallocated at register +# time, so it stays safe to compress from inside a panic. The others stay off. +CONFIG_PSTORE_ZLIB_COMPRESS=y # CONFIG_PSTORE_LZO_COMPRESS is not set # CONFIG_PSTORE_LZ4_COMPRESS is not set CONFIG_PSTORE_CONSOLE=y From e9414c8ae677c2d4c396fe7ac5434976239fe2bf Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:00:26 +0300 Subject: [PATCH 4/6] init: match root= exactly, so a "ram" in the cmdline is not a ramdisk The flash-root test grepped the whole kernel command line for a bare "ram"/"mmcblk"/"nfs", so any unrelated token spelled with those letters made init believe the root was a ramdisk / SD / NFS mount. It then skipped the flash overlay mount and pivot_root entirely and fell through to /sbin/init on the read-only squashfs: the camera came up with a read-only /etc, its saved password gone (unclaimed), and -- because /etc/fw_env could not be written -- load_goke fell back to the default osmem and the mmz zone collided with kernel RAM, so nothing streamed. The trigger was the pstore "ramoops.*" crash-log parameters, but the bug is the unanchored match; anchor all three to the root= value. A flash board's cmdline carries none of these letters in root=, so its result is unchanged; only a command line that mentioned them outside root= (as ramoops does) is fixed. Found on a gk7205v200 (UART recovery) while bringing up pstore. --- general/overlay/init | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/general/overlay/init b/general/overlay/init index 615f62c907..a3b7823dbb 100755 --- a/general/overlay/init +++ b/general/overlay/init @@ -12,8 +12,12 @@ grep -q overlay /proc/filesystems || exit 1 is_flash_root=true is_nfs_root=false -grep -q 'root=.*nfs\|mmcblk\|ram' /proc/cmdline && is_flash_root=false -grep -q 'root=.*nfs' /proc/cmdline && is_nfs_root=true +# Anchor these to the root= value. A bare "ram"/"mmcblk"/"nfs" matched the whole +# command line, so any unrelated token carrying those letters -- e.g. the +# "ramoops" crash-log parameters -- was mistaken for a ramdisk/SD/NFS root, the +# flash overlay was never mounted, and the camera booted read-only and unclaimed. +grep -qE 'root=[^ ]*(nfs|mmcblk|ram)' /proc/cmdline && is_flash_root=false +grep -qE 'root=[^ ]*nfs' /proc/cmdline && is_nfs_root=true if $is_flash_root; then if grep -q ubifs /proc/cmdline; then From 956ddb31d69b307d7260899bc6b926bba3a15c9d Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:41:08 +0300 Subject: [PATCH 5/6] gk7205v200: land ramoops just above the cma media zone, clear of CMA rounding and U-Boot set_allocator cma hung the board right after "Starting kernel" -- an early panic() before the console. Two constraints, both found on hardware, decide where ramoops can go on the cma path: - The media zone is a cma region, reserved with dma_declare_contiguous(), which rounds the region up to the CMA alignment (PAGE_SIZE << max(MAX_ORDER-1, pageblock_order) = 4M on this kernel) and rejects a fixed region whose rounded end runs past the end of RAM (mm/cma.c: "fixed && base + size > highmem_start"). drivers/goke/cma/cma.c turns that -EINVAL into a panic() from an early initcall. The first attempt shrank the zone by 1M, which rounded back up to the full size and overran mem= by 1M -> panic. The zone has to end on a 4M boundary at or below mem=, so drop a whole 4M (totalmem-osmem-4, still 4M-aligned since osmem/totalmem are 4M multiples). - ramoops then cannot go in the freed top 128K either: U-Boot relocates to the top of DRAM on every boot (bdinfo here: relocaddr 0x43F20000, page tables 0x43FF0000 -- the top ~1.25M), so a crash log left there is overwritten by the reboot before the kernel reads it back (seen as an empty /sys/fs/pstore after a panic). Land ramoops at the media zone's end instead and stop mem= there, well clear of both the kernel's RAM and U-Boot's window. On a cma board (>=128M) the 4M is negligible; gk7205v200 is 64M and always runs the gk allocator, so this branch is only reached by a manual override. Verified on a gk7205v200: cma now boots, streams, and captures a panic to /sys/fs/pstore across the reboot. --- .../files/script/set_allocator | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/general/package/goke-osdrv-gk7205v200/files/script/set_allocator b/general/package/goke-osdrv-gk7205v200/files/script/set_allocator index fd6b18b7fb..331ad3d856 100755 --- a/general/package/goke-osdrv-gk7205v200/files/script/set_allocator +++ b/general/package/goke-osdrv-gk7205v200/files/script/set_allocator @@ -30,16 +30,33 @@ calc_mmz() { os_mem_size=$(fw_printenv -n osmem | tr -d 'M') os_mem_size=${os_mem_size:=32} mmz_start=$(echo "$mem_start $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1/1024/1024 + $2; } END { printf("0x%x00000\n", temp); }') - # Reserve the top 1M of DRAM for ramoops (see below), so the media zone stops - # 1M short of the end. mmz is M-granular here, so reserving a whole M keeps it - # aligned; a cma board has >=128M, so the loss is negligible. - mmz_size=$(echo "$mem_total $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1 - $2 - 1; } END { printf("%dM\n", temp); }') + # ramoops sits in the gap between the media zone and the top of DRAM, and the + # gap is a whole 4M for two reasons that are both out of our hands here: + # + # * The media zone is a cma region, reserved with dma_declare_contiguous(), + # which rounds the region up to the CMA alignment -- PAGE_SIZE << + # max(MAX_ORDER-1, pageblock_order), 4M on this kernel -- and rejects a fixed + # region whose rounded end runs past the end of RAM (mm/cma.c: + # "fixed && base + size > highmem_start"). goke's cma.c turns that -EINVAL + # into a panic() from an early initcall, before the console, so a media zone + # that overruns mem= by even 1M hangs the board right after "Starting + # kernel". So the zone has to end on a 4M boundary at or below mem=; dropping + # one 4M step (totalmem-osmem-4, still 4M-aligned since osmem and totalmem + # are 4M multiples) is the smallest that satisfies it. + # * ramoops cannot instead go in the top 128K: U-Boot relocates itself to the + # top of DRAM on every boot (on this board bdinfo shows relocaddr 0x43F20000, + # page tables at 0x43FF0000 -- the top ~1.25M), so a crash log left up there + # is overwritten by the reboot before the kernel can read it back (verified: + # empty /sys/fs/pstore after a panic). Landing it just above the media zone + # keeps it clear of both the kernel's RAM and U-Boot's window. + # + # So put ramoops at the media zone's end and stop mem= there. On a cma board + # (>=128M) the 4M is negligible; gk7205v200 is 64M and never runs cma, so this + # branch is only reached by a manual override. + mmz_size=$(echo "$mem_total $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1 - $2 - 4; } END { printf("%dM\n", temp); }') mmz=anonymous,0,$mmz_start,$mmz_size - # ramoops lives in that reserved top megabyte, above both the (reduced) kernel - # window and the media zone. cma_mem is the OS size with the same 1M removed, - # so the kernel never maps the ramoops region. - cma_ramoops_addr=$(printf '0x%08x' $((0x40000000 + (mem_total - 1) * 1024 * 1024))) - cma_mem="$((mem_total - 1))M" + cma_ramoops_addr=$(printf '0x%08x' $(( 0x40000000 + (mem_total - 4) * 1024 * 1024 ))) + cma_mem="$(( mem_total - 4 ))M" } From 64bb02a8a2d8b960a5c4f476c00b1925e264d2f6 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Thu, 10 Sep 2026 18:25:58 +0300 Subject: [PATCH 6/6] gk7205v200: drop the set_allocator ramoops carve; reserve it in the device tree The ramoops region is now reserved by a /reserved-memory node in the board DTS (OpenIPC/linux), which costs exactly 128K and leaves mem= and the media (mmz/cma) zone untouched, so it works for both allocators. Carving it out of bootargs here could not: on the cma path the media zone is a CMA region that dma_declare_contiguous() rounds up to the 4M CMA alignment, so making room for a 128K log cost a full 4M and, done wrong, paniced the board before the console. Revert set_allocator to exactly its pre-pstore form (no ramoops parameters, no mem/media reduction). CONFIG_PSTORE_RAM and the S29pstore mount stay; the driver binds to the DT region. Needs the OpenIPC/linux DTS node to actually capture a crash, but is harmless without it (pstore just mounts empty). No conflict in either landing order, since bootargs no longer carry ramoops.* to clash with the DT node. --- .../files/script/set_allocator | 56 ++----------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/general/package/goke-osdrv-gk7205v200/files/script/set_allocator b/general/package/goke-osdrv-gk7205v200/files/script/set_allocator index 331ad3d856..50231ce523 100755 --- a/general/package/goke-osdrv-gk7205v200/files/script/set_allocator +++ b/general/package/goke-osdrv-gk7205v200/files/script/set_allocator @@ -1,13 +1,5 @@ #!/bin/sh -# 128K pstore/ramoops crash-log region: one 64K panic dump + headroom. -# Console zone 0 (the console is muted on these boards) -- rely on the -# oops/panic kmsg_dump, which is console-independent. -RAMOOPS_SIZE=0x20000 -ramoops_args() { # $1 = physical base address - echo "ramoops.mem_address=$1 ramoops.mem_size=${RAMOOPS_SIZE} ramoops.record_size=0x10000 ramoops.console_size=0 ramoops.pmsg_size=0 ramoops.dump_oops=1" -} - get_env() { bootargs=$(fw_printenv -n bootargs) @@ -30,53 +22,16 @@ calc_mmz() { os_mem_size=$(fw_printenv -n osmem | tr -d 'M') os_mem_size=${os_mem_size:=32} mmz_start=$(echo "$mem_start $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1/1024/1024 + $2; } END { printf("0x%x00000\n", temp); }') - # ramoops sits in the gap between the media zone and the top of DRAM, and the - # gap is a whole 4M for two reasons that are both out of our hands here: - # - # * The media zone is a cma region, reserved with dma_declare_contiguous(), - # which rounds the region up to the CMA alignment -- PAGE_SIZE << - # max(MAX_ORDER-1, pageblock_order), 4M on this kernel -- and rejects a fixed - # region whose rounded end runs past the end of RAM (mm/cma.c: - # "fixed && base + size > highmem_start"). goke's cma.c turns that -EINVAL - # into a panic() from an early initcall, before the console, so a media zone - # that overruns mem= by even 1M hangs the board right after "Starting - # kernel". So the zone has to end on a 4M boundary at or below mem=; dropping - # one 4M step (totalmem-osmem-4, still 4M-aligned since osmem and totalmem - # are 4M multiples) is the smallest that satisfies it. - # * ramoops cannot instead go in the top 128K: U-Boot relocates itself to the - # top of DRAM on every boot (on this board bdinfo shows relocaddr 0x43F20000, - # page tables at 0x43FF0000 -- the top ~1.25M), so a crash log left up there - # is overwritten by the reboot before the kernel can read it back (verified: - # empty /sys/fs/pstore after a panic). Landing it just above the media zone - # keeps it clear of both the kernel's RAM and U-Boot's window. - # - # So put ramoops at the media zone's end and stop mem= there. On a cma board - # (>=128M) the 4M is negligible; gk7205v200 is 64M and never runs cma, so this - # branch is only reached by a manual override. - mmz_size=$(echo "$mem_total $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1 - $2 - 4; } END { printf("%dM\n", temp); }') + mmz_size=$(echo "$mem_total $os_mem_size" | awk 'BEGIN { temp = 0; } { temp = $1 - $2; } END { printf("%dM\n", temp); }') mmz=anonymous,0,$mmz_start,$mmz_size - cma_ramoops_addr=$(printf '0x%08x' $(( 0x40000000 + (mem_total - 4) * 1024 * 1024 ))) - cma_mem="$(( mem_total - 4 ))M" } if [[ "$1" == 'gk' ]]; then echo "Allocator selected as gk..." get_env - osmem=${osmem:=32M} - # Carve 128K off the TOP of the OS window for a ramoops crash-log region - # (pstore). It lands above the shrunk kernel window and below mmz_start - # (= base + osmem, unchanged), so it touches neither Linux RAM nor the media - # (mmz) pool -- the kernel never maps it and the gk allocator never sees it. - # kmsg_dump writes here on a panic/oops, so a crash survives the panic=20 - # reboot even though the console is muted. mem_address MUST equal - # base(0x40000000) + (osmem - 128K). - osk=$(echo "$osmem" | awk '{ gsub(/[Mm]/,""); printf "%d", $1 * 1024 }') - memk=$((osk - 128)) - raddr=$(printf '0x%08x' $((0x40000000 + memk * 1024))) - mem="${memk}K" - ramoops=$(ramoops_args "${raddr}") - newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=gk ${ramoops} ${extras}" + mem=${osmem:=32M} + newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=gk ${extras}" echo ${newbootargs} fw_setenv bootargs ${newbootargs} # @@ -84,9 +39,8 @@ elif [[ "$1" == 'cma' ]]; then echo "Allocator selected as cma..." get_env calc_mmz - mem=${cma_mem:=${totalmem:=64M}} - ramoops=$(ramoops_args "${cma_ramoops_addr}") - newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=cma mmz=${mmz} ${ramoops} ${extras}" + mem=${totalmem:=64M} + newbootargs="mem=${mem} console=${console} panic=${panic} rootfstype=${rootfstype} root=${root} init=${init} mtdparts=${mtdparts} mmz_allocator=cma mmz=${mmz} ${extras}" fw_setenv bootargs ${newbootargs} echo ${newbootargs} else