[syslinux] [PATCH v2] core: Check size of ldlinux.sys at building time.

Raphael S.Carvalho raphael.scarv at gmail.com
Sun Sep 29 22:14:34 PDT 2013


From: Raphael S. Carvalho <raphael.scarv at gmail.com>

v2: Extract ADV_SIZE automatically from libinstaller/setadv.h.

Calc the size of ldlinux.sys from ldlinux.bin, and check if it exceeds the limit.
ldlinux.sys must fit between the bootsector and two copies of ADV whose size may vary.
Thus, the size of ldlinux.sys can be at most: 65536 - 2 * ADV_SIZE - 512 (limit).

Certain file systems (such as BTRFS and UFS2) will rely on ldlinux.sys being installed on the 0-64k range,
thus it can't exceed the limit, otherwise the superblock would be corrupted.

Signed-off-by: Raphael S. Carvalho <raphael.scarv at gmail.com>
Suggested-by: Matt Fleming <matt at console-pimps.org>
---
 core/Makefile         |    1 +
 core/ldlinux_limit.pl |   80 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100755 core/ldlinux_limit.pl

diff --git a/core/Makefile b/core/Makefile
index a7503ef..635d8ab 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -224,6 +224,7 @@ ldlinux.bss: ldlinux.bin
 	dd if=$< of=$@ bs=512 count=1

 ldlinux.sys: ldlinux.bin
+	$(PERL) $(SRC)/ldlinux_limit.pl $< \
 	dd if=$< of=$@ bs=512 skip=2

 codepage.cp: $(OBJ)/../codepage/$(CODEPAGE).cp
diff --git a/core/ldlinux_limit.pl b/core/ldlinux_limit.pl
new file mode 100755
index 0000000..9b0f409
--- /dev/null
+++ b/core/ldlinux_limit.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+## -----------------------------------------------------------------------
+##
+##   Copyright 2013 Raphael S. Carvalho <raphael.scarv at gmail.com>
+##
+##   This program is free software; you can redistribute it and/or modify
+##   it under the terms of the GNU General Public License as published by
+##   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+##   Boston MA 02111-1307, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+## ldlinux_limit.pl: Calc the size of ldlinux.sys and check if it exceeds the limit.
+## ldlinux.sys must fit between the bootsector and two copies of ADV whose size may vary.
+##
+## Certain file systems will simply install ldlinux.sys as an ordinary file, but UFS2 and
+## BTRFS for example, rely on ldlinux.sys being installed on the 0-64k range.
+##
+## 0-64k range:
+## [0](bootsector)[512](ldlinux.sys)[65536 - 2 * ADV_SIZE](2 copies of ADV)[65536]
+
+use File::stat;
+use constant DEBUG => (1);
+
+# CWD is 'bios/core' when this script gets executed.
+$file = '../../libinstaller/setadv.h';
+$target_id = '#define ADV_SIZE';
+
+sub get_ADV_SIZE {
+    my $data, $line;
+    my $adv_size = -1;
+
+    open $data, "<", $file or die "Cannot open $file\n";
+    while ( $line = <$data> ) {
+	my $id, $value;
+
+	chomp($line);
+	($id, $value) = split('\t', $line);
+
+	if ( index($id, $target_id) != -1 ) {
+	    $adv_size = $value;
+	    break;
+	}
+    }
+    close $data or die "Cannot close $file\n";
+    return $adv_size;
+}
+
+$min_adv_size = 512;
+$adv_size = get_ADV_SIZE();
+if ( $adv_size == -1 ) {
+    print STDERR "$0: '$target_id' was not found at: '$file'\n",
+		 "$0: Please check the file and try again!\n";
+    exit 1;
+} elsif ( $adv_size < $min_adv_size ) {
+    print STDERR "$0: adv_size read from '$file' ($adv_size bytes) is lower ",
+		 "than the minimum allowed value ($min_adv_size bytes)\n",
+		 "$0: Please check the file and try again!\n";
+    exit 1;
+}
+
+($ldlinux_bin) = @ARGV;
+$limit = 65536 - 2 * $adv_size - 512;
+$pad = 512;
+
+# Calc size of ldlinux.sys from ldlinux.bin
+$ldlinux_size = stat($ldlinux_bin)->size - 1024;
+$align = $ldlinux_size % $pad;
+$ldlinux_size += $pad - $align;
+
+print STDERR "$0: ldlinux.sys: $ldlinux_size bytes, limit: $limit bytes, ",
+	     "adv_size: $adv_size bytes\n", if DEBUG;
+
+if ( $ldlinux_size > $limit ) {
+    print STDERR "$0: ldlinux.sys ($ldlinux_size bytes) is ",
+		 "larger than the limit ($limit bytes).\n";
+    exit 1;
+}
+exit 0;
--
1.7.2.5



More information about the Syslinux mailing list